x86, sparseirq: move irq_desc according to smp_affinity, v7

Impact: improve NUMA handling by migrating irq_desc on smp_affinity changes

if CONFIG_NUMA_MIGRATE_IRQ_DESC is set:

-  make irq_desc to go with affinity aka irq_desc moving etc
-  call move_irq_desc in irq_complete_move()
-  legacy irq_desc is not moved, because they are allocated via static array

for logical apic mode, need to add move_desc_in_progress_in_same_domain,
otherwise it will not be moved ==> also could need two phases to get
irq_desc moved.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Yinghai Lu 2008-12-11 00:15:01 -08:00 committed by Ingo Molnar
parent 13bd41bc22
commit 48a1b10aff
8 changed files with 313 additions and 8 deletions

View file

@ -23,7 +23,7 @@
/*
* lockdep: we want to handle all irq_desc locks as a single lock-class:
*/
static struct lock_class_key irq_desc_lock_class;
struct lock_class_key irq_desc_lock_class;
/**
* handle_bad_irq - handle spurious and unhandled irqs
@ -73,7 +73,7 @@ static struct irq_desc irq_desc_init = {
#endif
};
static void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
{
unsigned long bytes;
char *ptr;
@ -113,7 +113,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
/*
* Protect the sparse_irqs:
*/
static DEFINE_SPINLOCK(sparse_irq_lock);
DEFINE_SPINLOCK(sparse_irq_lock);
struct irq_desc *irq_desc_ptrs[NR_IRQS] __read_mostly;
@ -337,8 +337,11 @@ unsigned int __do_IRQ(unsigned int irq)
/*
* No locking required for CPU-local interrupts:
*/
if (desc->chip->ack)
if (desc->chip->ack) {
desc->chip->ack(irq);
/* get new one */
desc = irq_remap_to_desc(irq, desc);
}
if (likely(!(desc->status & IRQ_DISABLED))) {
action_ret = handle_IRQ_event(irq, desc->action);
if (!noirqdebug)
@ -349,8 +352,10 @@ unsigned int __do_IRQ(unsigned int irq)
}
spin_lock(&desc->lock);
if (desc->chip->ack)
if (desc->chip->ack) {
desc->chip->ack(irq);
desc = irq_remap_to_desc(irq, desc);
}
/*
* REPLAY is when Linux resends an IRQ that was dropped earlier
* WAITING is used by probe to mark irqs that are being tested