Skip to content

Commit 1bf2fc3

Browse files
lyan3lijinxia
authored andcommitted
hv: pirq: refactor irq num alloc/free
This commit refactors the alloc/free irq num, two functions are defined: - uint32_t alloc_irq_num(uint32_t irq) - if irq is valid, mark the irq_desc as used; if it's IRQ_INVALID, alloc a free irq, or else do nothing; - return: irq num on success, or IRQ_INVALID on failure. - void free_irq_num(uint32_t irq) - free the irq num allocated via alloc_irq_num(); And a global spinlock to protect it from concurrent allocation/free. Signed-off-by: Yan, Like <like.yan@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent f77d885 commit 1bf2fc3

File tree

4 files changed

+44
-40
lines changed

4 files changed

+44
-40
lines changed

hypervisor/arch/x86/ioapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ void setup_ioapic_irq(void)
361361
}
362362

363363
/* pinned irq before use it */
364-
if (irq_mark_used(gsi) >= NR_IRQS) {
364+
if (alloc_irq_num(gsi) == IRQ_INVALID) {
365365
pr_err("failed to alloc IRQ[%d]", gsi);
366366
gsi++;
367367
continue;

hypervisor/arch/x86/irq.c

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <softirq.h>
99

1010
static spinlock_t exception_spinlock = { .head = 0U, .tail = 0U, };
11+
static spinlock_t irq_alloc_spinlock = { .head = 0U, .tail = 0U, };
1112

1213
static struct irq_desc irq_desc_array[NR_IRQS];
1314
static uint32_t vector_to_irq[NR_MAX_VECTOR + 1];
@@ -62,49 +63,60 @@ static uint32_t find_available_vector()
6263
}
6364

6465
/*
65-
* check and set irq to be assigned
66-
* return: IRQ_INVALID if irq already assigned otherwise return irq
66+
* alloc an free irq if req_irq is IRQ_INVALID, or else set assigned
67+
* return: irq num on success, IRQ_INVALID on failure
6768
*/
68-
uint32_t irq_mark_used(uint32_t irq)
69+
uint32_t alloc_irq_num(uint32_t req_irq)
6970
{
71+
uint32_t i;
72+
uint32_t irq = req_irq;
7073
uint64_t rflags;
7174
struct irq_desc *desc;
7275

73-
if (irq >= NR_IRQS) {
76+
if ((irq >= NR_IRQS) && (irq != IRQ_INVALID)) {
77+
pr_err("[%s] invalid req_irq %u", __func__, req_irq);
7478
return IRQ_INVALID;
7579
}
7680

77-
desc = &irq_desc_array[irq];
78-
spinlock_irqsave_obtain(&desc->lock, &rflags);
79-
if (desc->used == IRQ_NOT_ASSIGNED) {
81+
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
82+
if (irq == IRQ_INVALID) {
83+
/* if no valid irq num given, find a free one */
84+
for (i = irq_gsi_num(); i < NR_IRQS; i++) {
85+
desc = &irq_desc_array[i];
86+
if (desc->used == IRQ_NOT_ASSIGNED) {
87+
irq = i;
88+
break;
89+
}
90+
}
91+
}
92+
93+
if (irq != IRQ_INVALID) {
94+
desc = &irq_desc_array[irq];
8095
desc->used = IRQ_ASSIGNED;
8196
}
82-
spinlock_irqrestore_release(&desc->lock, rflags);
97+
spinlock_irqrestore_release(&irq_alloc_spinlock, rflags);
8398
return irq;
8499
}
85100

86101
/*
87-
* system find available irq and set assigned
88-
* return: irq, VECTOR_INVALID not found
102+
* free irq num allocated via alloc_irq_num()
89103
*/
90-
static uint32_t alloc_irq(void)
104+
void free_irq_num(uint32_t irq)
91105
{
92-
uint32_t i;
93-
uint64_t rflags;
94106
struct irq_desc *desc;
107+
uint64_t rflags;
95108

109+
if (irq >= NR_IRQS) {
110+
return;
111+
}
96112

97-
for (i = irq_gsi_num(); i < NR_IRQS; i++) {
98-
desc = &irq_desc_array[i];
99-
spinlock_irqsave_obtain(&desc->lock, &rflags);
100-
if (desc->used == IRQ_NOT_ASSIGNED) {
101-
desc->used = IRQ_ASSIGNED;
102-
spinlock_irqrestore_release(&desc->lock, rflags);
103-
break;
104-
}
105-
spinlock_irqrestore_release(&desc->lock, rflags);
113+
desc = &irq_desc_array[irq];
114+
if ((irq_is_gsi(irq) == false)
115+
&& (desc->vector <= VECTOR_DYNAMIC_END)) {
116+
spinlock_irqsave_obtain(&irq_alloc_spinlock, &rflags);
117+
desc->used = IRQ_NOT_ASSIGNED;
118+
spinlock_irqrestore_release(&irq_alloc_spinlock, rflags);
106119
}
107-
return (i == NR_IRQS) ? IRQ_INVALID : i;
108120
}
109121

110122
/* need lock protection before use */
@@ -163,12 +175,12 @@ static void disable_pic_irq(void)
163175
pio_write8(0xffU, 0x21U);
164176
}
165177

166-
int32_t request_irq(uint32_t irq_arg,
178+
int32_t request_irq(uint32_t req_irq,
167179
irq_action_t action_fn,
168180
void *priv_data)
169181
{
170182
struct irq_desc *desc;
171-
uint32_t irq = irq_arg, vector;
183+
uint32_t irq, vector;
172184
uint64_t rflags;
173185

174186
/* ======================================================
@@ -198,18 +210,9 @@ int32_t request_irq(uint32_t irq_arg,
198210
*
199211
* =====================================================
200212
*/
201-
202-
/* HV select a irq for device if irq < 0
203-
* this vector/irq match to APCI DSDT or PCI INTx/MSI
204-
*/
213+
irq = alloc_irq_num(req_irq);
205214
if (irq == IRQ_INVALID) {
206-
irq = alloc_irq();
207-
} else {
208-
irq = irq_mark_used(irq);
209-
}
210-
211-
if (irq >= NR_IRQS) {
212-
pr_err("failed to assign IRQ");
215+
pr_err("[%s] invalid irq num", __func__);
213216
return -EINVAL;
214217
}
215218

@@ -228,7 +231,7 @@ int32_t request_irq(uint32_t irq_arg,
228231

229232
if (desc->vector == VECTOR_INVALID) {
230233
pr_err("the input vector is not correct");
231-
/* FIXME: free allocated irq */
234+
free_irq_num(irq);
232235
return -EINVAL;
233236
}
234237

@@ -531,6 +534,7 @@ void free_irq(uint32_t irq)
531534

532535
spinlock_irqrestore_release(&desc->lock, rflags);
533536
irq_desc_try_free_vector(desc->irq);
537+
free_irq_num(irq);
534538
}
535539

536540
#ifdef HV_DEBUG

hypervisor/include/arch/x86/irq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ void setup_notification(void);
7474
typedef void (*spurious_handler_t)(uint32_t vector);
7575
extern spurious_handler_t spurious_handler;
7676

77+
uint32_t alloc_irq_num(uint32_t req_irq);
78+
7779
/*
7880
* Some MSI message definitions
7981
*/

hypervisor/include/common/irq.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ struct irq_desc {
3434
spinlock_t lock;
3535
};
3636

37-
uint32_t irq_mark_used(uint32_t irq);
38-
3937
uint32_t irq_desc_alloc_vector(uint32_t irq);
4038
void irq_desc_try_free_vector(uint32_t irq);
4139

0 commit comments

Comments
 (0)