aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig10
-rw-r--r--arch/x86/configs/x86_64_defconfig1
-rw-r--r--arch/x86/kernel/apic/io_apic.c56
-rw-r--r--include/linux/irq.h10
-rw-r--r--kernel/irq/Makefile2
-rw-r--r--kernel/irq/chip.c12
-rw-r--r--kernel/irq/handle.c9
-rw-r--r--kernel/irq/numa_migrate.c2
8 files changed, 9 insertions, 93 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index df9e885eee14..e1b2543f8ed3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -274,16 +274,6 @@ config SPARSE_IRQ
274 274
275 If you don't know what to do here, say N. 275 If you don't know what to do here, say N.
276 276
277config NUMA_MIGRATE_IRQ_DESC
278 bool "Move irq desc when changing irq smp_affinity"
279 depends on SPARSE_IRQ && NUMA
280 depends on BROKEN
281 default n
282 ---help---
283 This enables moving irq_desc to cpu/node that irq will use handled.
284
285 If you don't know what to do here, say N.
286
287config X86_MPPARSE 277config X86_MPPARSE
288 bool "Enable MPS table" if ACPI 278 bool "Enable MPS table" if ACPI
289 default y 279 default y
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index 9fe5d212ab4c..27b8ce0f5908 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -195,7 +195,6 @@ CONFIG_HIGH_RES_TIMERS=y
195CONFIG_GENERIC_CLOCKEVENTS_BUILD=y 195CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
196CONFIG_SMP=y 196CONFIG_SMP=y
197CONFIG_SPARSE_IRQ=y 197CONFIG_SPARSE_IRQ=y
198# CONFIG_NUMA_MIGRATE_IRQ_DESC is not set
199CONFIG_X86_FIND_SMP_CONFIG=y 198CONFIG_X86_FIND_SMP_CONFIG=y
200CONFIG_X86_MPPARSE=y 199CONFIG_X86_MPPARSE=y
201# CONFIG_X86_ELAN is not set 200# CONFIG_X86_ELAN is not set
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 30da617d18e4..9fbf0f7ec7eb 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -148,9 +148,6 @@ struct irq_cfg {
148 unsigned move_cleanup_count; 148 unsigned move_cleanup_count;
149 u8 vector; 149 u8 vector;
150 u8 move_in_progress : 1; 150 u8 move_in_progress : 1;
151#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
152 u8 move_desc_pending : 1;
153#endif
154}; 151};
155 152
156/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ 153/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
@@ -254,8 +251,7 @@ int arch_init_chip_data(struct irq_desc *desc, int cpu)
254 return 0; 251 return 0;
255} 252}
256 253
257#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC 254/* for move_irq_desc */
258
259static void 255static void
260init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu) 256init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
261{ 257{
@@ -356,19 +352,7 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
356 old_desc->chip_data = NULL; 352 old_desc->chip_data = NULL;
357 } 353 }
358} 354}
359 355/* end for move_irq_desc */
360static void
361set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
362{
363 struct irq_cfg *cfg = desc->chip_data;
364
365 if (!cfg->move_in_progress) {
366 /* it means that domain is not changed */
367 if (!cpumask_intersects(desc->affinity, mask))
368 cfg->move_desc_pending = 1;
369 }
370}
371#endif
372 356
373#else 357#else
374static struct irq_cfg *irq_cfg(unsigned int irq) 358static struct irq_cfg *irq_cfg(unsigned int irq)
@@ -378,13 +362,6 @@ static struct irq_cfg *irq_cfg(unsigned int irq)
378 362
379#endif 363#endif
380 364
381#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC
382static inline void
383set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
384{
385}
386#endif
387
388struct io_apic { 365struct io_apic {
389 unsigned int index; 366 unsigned int index;
390 unsigned int unused[3]; 367 unsigned int unused[3];
@@ -592,9 +569,6 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
592 if (assign_irq_vector(irq, cfg, mask)) 569 if (assign_irq_vector(irq, cfg, mask))
593 return BAD_APICID; 570 return BAD_APICID;
594 571
595 /* check that before desc->addinity get updated */
596 set_extra_move_desc(desc, mask);
597
598 cpumask_copy(desc->affinity, mask); 572 cpumask_copy(desc->affinity, mask);
599 573
600 return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); 574 return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
@@ -2393,8 +2367,6 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
2393 if (assign_irq_vector(irq, cfg, mask)) 2367 if (assign_irq_vector(irq, cfg, mask))
2394 return; 2368 return;
2395 2369
2396 set_extra_move_desc(desc, mask);
2397
2398 dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); 2370 dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
2399 2371
2400 irte.vector = cfg->vector; 2372 irte.vector = cfg->vector;
@@ -2491,34 +2463,14 @@ static void irq_complete_move(struct irq_desc **descp)
2491 struct irq_cfg *cfg = desc->chip_data; 2463 struct irq_cfg *cfg = desc->chip_data;
2492 unsigned vector, me; 2464 unsigned vector, me;
2493 2465
2494 if (likely(!cfg->move_in_progress)) { 2466 if (likely(!cfg->move_in_progress))
2495#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
2496 if (likely(!cfg->move_desc_pending))
2497 return;
2498
2499 /* domain has not changed, but affinity did */
2500 me = smp_processor_id();
2501 if (cpumask_test_cpu(me, desc->affinity)) {
2502 *descp = desc = move_irq_desc(desc, me);
2503 /* get the new one */
2504 cfg = desc->chip_data;
2505 cfg->move_desc_pending = 0;
2506 }
2507#endif
2508 return; 2467 return;
2509 }
2510 2468
2511 vector = ~get_irq_regs()->orig_ax; 2469 vector = ~get_irq_regs()->orig_ax;
2512 me = smp_processor_id(); 2470 me = smp_processor_id();
2513 2471
2514 if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { 2472 if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
2515#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
2516 *descp = desc = move_irq_desc(desc, me);
2517 /* get the new one */
2518 cfg = desc->chip_data;
2519#endif
2520 send_cleanup_vector(cfg); 2473 send_cleanup_vector(cfg);
2521 }
2522} 2474}
2523#else 2475#else
2524static inline void irq_complete_move(struct irq_desc **descp) {} 2476static inline void irq_complete_move(struct irq_desc **descp) {}
diff --git a/include/linux/irq.h b/include/linux/irq.h
index c4953cf27e5e..2a34cd6281d7 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -212,16 +212,6 @@ extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
212 212
213extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu); 213extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
214 214
215static inline struct irq_desc *
216irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
217{
218#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
219 return irq_to_desc(irq);
220#else
221 return desc;
222#endif
223}
224
225/* 215/*
226 * Migration helpers for obsolete names, they will go away: 216 * Migration helpers for obsolete names, they will go away:
227 */ 217 */
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index 3394f8f52964..2f065277f8ee 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -3,5 +3,5 @@ obj-y := handle.o manage.o spurious.o resend.o chip.o devres.o
3obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o 3obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
4obj-$(CONFIG_PROC_FS) += proc.o 4obj-$(CONFIG_PROC_FS) += proc.o
5obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o 5obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
6obj-$(CONFIG_NUMA_MIGRATE_IRQ_DESC) += numa_migrate.o 6obj-$(CONFIG_SPARSE_IRQ) += numa_migrate.o
7obj-$(CONFIG_PM_SLEEP) += pm.o 7obj-$(CONFIG_PM_SLEEP) += pm.o
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index c687ba4363f2..13c68e71b726 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -359,7 +359,6 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
359 359
360 spin_lock(&desc->lock); 360 spin_lock(&desc->lock);
361 mask_ack_irq(desc, irq); 361 mask_ack_irq(desc, irq);
362 desc = irq_remap_to_desc(irq, desc);
363 362
364 if (unlikely(desc->status & IRQ_INPROGRESS)) 363 if (unlikely(desc->status & IRQ_INPROGRESS))
365 goto out_unlock; 364 goto out_unlock;
@@ -438,7 +437,6 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
438 desc->status &= ~IRQ_INPROGRESS; 437 desc->status &= ~IRQ_INPROGRESS;
439out: 438out:
440 desc->chip->eoi(irq); 439 desc->chip->eoi(irq);
441 desc = irq_remap_to_desc(irq, desc);
442 440
443 spin_unlock(&desc->lock); 441 spin_unlock(&desc->lock);
444} 442}
@@ -475,7 +473,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
475 !desc->action)) { 473 !desc->action)) {
476 desc->status |= (IRQ_PENDING | IRQ_MASKED); 474 desc->status |= (IRQ_PENDING | IRQ_MASKED);
477 mask_ack_irq(desc, irq); 475 mask_ack_irq(desc, irq);
478 desc = irq_remap_to_desc(irq, desc);
479 goto out_unlock; 476 goto out_unlock;
480 } 477 }
481 kstat_incr_irqs_this_cpu(irq, desc); 478 kstat_incr_irqs_this_cpu(irq, desc);
@@ -483,7 +480,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
483 /* Start handling the irq */ 480 /* Start handling the irq */
484 if (desc->chip->ack) 481 if (desc->chip->ack)
485 desc->chip->ack(irq); 482 desc->chip->ack(irq);
486 desc = irq_remap_to_desc(irq, desc);
487 483
488 /* Mark the IRQ currently in progress.*/ 484 /* Mark the IRQ currently in progress.*/
489 desc->status |= IRQ_INPROGRESS; 485 desc->status |= IRQ_INPROGRESS;
@@ -544,10 +540,8 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
544 if (!noirqdebug) 540 if (!noirqdebug)
545 note_interrupt(irq, desc, action_ret); 541 note_interrupt(irq, desc, action_ret);
546 542
547 if (desc->chip->eoi) { 543 if (desc->chip->eoi)
548 desc->chip->eoi(irq); 544 desc->chip->eoi(irq);
549 desc = irq_remap_to_desc(irq, desc);
550 }
551} 545}
552 546
553void 547void
@@ -582,10 +576,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
582 576
583 /* Uninstall? */ 577 /* Uninstall? */
584 if (handle == handle_bad_irq) { 578 if (handle == handle_bad_irq) {
585 if (desc->chip != &no_irq_chip) { 579 if (desc->chip != &no_irq_chip)
586 mask_ack_irq(desc, irq); 580 mask_ack_irq(desc, irq);
587 desc = irq_remap_to_desc(irq, desc);
588 }
589 desc->status |= IRQ_DISABLED; 581 desc->status |= IRQ_DISABLED;
590 desc->depth = 1; 582 desc->depth = 1;
591 } 583 }
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 882c79800107..3e0cbc44bd73 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -458,11 +458,8 @@ unsigned int __do_IRQ(unsigned int irq)
458 /* 458 /*
459 * No locking required for CPU-local interrupts: 459 * No locking required for CPU-local interrupts:
460 */ 460 */
461 if (desc->chip->ack) { 461 if (desc->chip->ack)
462 desc->chip->ack(irq); 462 desc->chip->ack(irq);
463 /* get new one */
464 desc = irq_remap_to_desc(irq, desc);
465 }
466 if (likely(!(desc->status & IRQ_DISABLED))) { 463 if (likely(!(desc->status & IRQ_DISABLED))) {
467 action_ret = handle_IRQ_event(irq, desc->action); 464 action_ret = handle_IRQ_event(irq, desc->action);
468 if (!noirqdebug) 465 if (!noirqdebug)
@@ -473,10 +470,8 @@ unsigned int __do_IRQ(unsigned int irq)
473 } 470 }
474 471
475 spin_lock(&desc->lock); 472 spin_lock(&desc->lock);
476 if (desc->chip->ack) { 473 if (desc->chip->ack)
477 desc->chip->ack(irq); 474 desc->chip->ack(irq);
478 desc = irq_remap_to_desc(irq, desc);
479 }
480 /* 475 /*
481 * REPLAY is when Linux resends an IRQ that was dropped earlier 476 * REPLAY is when Linux resends an IRQ that was dropped earlier
482 * WAITING is used by probe to mark irqs that are being tested 477 * WAITING is used by probe to mark irqs that are being tested
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 5760d7251626..ce72bc3f4ced 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -97,9 +97,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
97 97
98 /* free the old one */ 98 /* free the old one */
99 free_one_irq_desc(old_desc, desc); 99 free_one_irq_desc(old_desc, desc);
100 spin_unlock(&old_desc->lock);
101 kfree(old_desc); 100 kfree(old_desc);
102 spin_lock(&desc->lock);
103 101
104 return desc; 102 return desc;
105 103