diff options
-rw-r--r-- | arch/x86/kernel/apic/vector.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index f47069e8efac..63d58b08a109 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c | |||
@@ -539,6 +539,9 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) | |||
539 | 539 | ||
540 | entering_ack_irq(); | 540 | entering_ack_irq(); |
541 | 541 | ||
542 | /* Prevent vectors vanishing under us */ | ||
543 | raw_spin_lock(&vector_lock); | ||
544 | |||
542 | me = smp_processor_id(); | 545 | me = smp_processor_id(); |
543 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { | 546 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { |
544 | int irq; | 547 | int irq; |
@@ -546,6 +549,7 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) | |||
546 | struct irq_desc *desc; | 549 | struct irq_desc *desc; |
547 | struct apic_chip_data *data; | 550 | struct apic_chip_data *data; |
548 | 551 | ||
552 | retry: | ||
549 | irq = __this_cpu_read(vector_irq[vector]); | 553 | irq = __this_cpu_read(vector_irq[vector]); |
550 | 554 | ||
551 | if (irq <= VECTOR_UNDEFINED) | 555 | if (irq <= VECTOR_UNDEFINED) |
@@ -555,12 +559,16 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) | |||
555 | if (!desc) | 559 | if (!desc) |
556 | continue; | 560 | continue; |
557 | 561 | ||
562 | if (!raw_spin_trylock(&desc->lock)) { | ||
563 | raw_spin_unlock(&vector_lock); | ||
564 | cpu_relax(); | ||
565 | raw_spin_lock(&vector_lock); | ||
566 | goto retry; | ||
567 | } | ||
568 | |||
558 | data = apic_chip_data(&desc->irq_data); | 569 | data = apic_chip_data(&desc->irq_data); |
559 | if (!data) | 570 | if (!data) |
560 | continue; | 571 | goto unlock; |
561 | |||
562 | raw_spin_lock(&desc->lock); | ||
563 | |||
564 | /* | 572 | /* |
565 | * Check if the irq migration is in progress. If so, we | 573 | * Check if the irq migration is in progress. If so, we |
566 | * haven't received the cleanup request yet for this irq. | 574 | * haven't received the cleanup request yet for this irq. |
@@ -589,6 +597,8 @@ unlock: | |||
589 | raw_spin_unlock(&desc->lock); | 597 | raw_spin_unlock(&desc->lock); |
590 | } | 598 | } |
591 | 599 | ||
600 | raw_spin_unlock(&vector_lock); | ||
601 | |||
592 | exiting_irq(); | 602 | exiting_irq(); |
593 | } | 603 | } |
594 | 604 | ||