diff options
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ff1759a1128..42cdc78427a 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -2414,6 +2414,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
| 2414 | me = smp_processor_id(); | 2414 | me = smp_processor_id(); |
| 2415 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { | 2415 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { |
| 2416 | unsigned int irq; | 2416 | unsigned int irq; |
| 2417 | unsigned int irr; | ||
| 2417 | struct irq_desc *desc; | 2418 | struct irq_desc *desc; |
| 2418 | struct irq_cfg *cfg; | 2419 | struct irq_cfg *cfg; |
| 2419 | irq = __get_cpu_var(vector_irq)[vector]; | 2420 | irq = __get_cpu_var(vector_irq)[vector]; |
| @@ -2433,6 +2434,18 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
| 2433 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) | 2434 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) |
| 2434 | goto unlock; | 2435 | goto unlock; |
| 2435 | 2436 | ||
| 2437 | irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); | ||
| 2438 | /* | ||
| 2439 | * Check if the vector that needs to be cleanedup is | ||
| 2440 | * registered at the cpu's IRR. If so, then this is not | ||
| 2441 | * the best time to clean it up. Lets clean it up in the | ||
| 2442 | * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR | ||
| 2443 | * to myself. | ||
| 2444 | */ | ||
| 2445 | if (irr & (1 << (vector % 32))) { | ||
| 2446 | apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); | ||
| 2447 | goto unlock; | ||
| 2448 | } | ||
| 2436 | __get_cpu_var(vector_irq)[vector] = -1; | 2449 | __get_cpu_var(vector_irq)[vector] = -1; |
| 2437 | cfg->move_cleanup_count--; | 2450 | cfg->move_cleanup_count--; |
| 2438 | unlock: | 2451 | unlock: |
