diff options
author | Zhang Yanmin <yanmin.zhang@intel.com> | 2006-06-23 05:04:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-23 10:42:57 -0400 |
commit | 1b61b910e99059abdd54c93aa70e84e076e33d16 (patch) | |
tree | fe2cd431dc39521a0f2d30e22c9bd3eb3e1bc317 /arch/i386/kernel/io_apic.c | |
parent | afa024c3dbccf026e45121f4b9de54cda48edbea (diff) |
[PATCH] x86: kernel irq balance doesn't work
On i386, kernel irq balance doesn't work.
1) In function do_irq_balance, after kernel finds the min_loaded cpu but
before calling set_pending_irq to really pin the selected_irq to the
target cpu, kernel does a cpus_and with irq_affinity[selected_irq].
Later on, when the irq is acked, kernel would calls
move_native_irq=>desc->handler->set_affinity to change the irq affinity.
However, every function pointed by
hw_interrupt_type->set_affinity(unsigned int irq, cpumask_t cpumask)
always changes irq_affinity[irq] to cpumask. Next time when recalling
do_irq_balance, it has to do cpu_ands again with
irq_affinity[selected_irq], but irq_affinity[selected_irq] already
becomes one cpu selected by the first irq balance.
2) Function balance_irq in file arch/i386/kernel/io_apic.c has the same
issue.
[akpm@osdl.org: cleanups]
Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d70f2ade5cde..a62df3e764c5 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -267,7 +267,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
267 | # include <linux/slab.h> /* kmalloc() */ | 267 | # include <linux/slab.h> /* kmalloc() */ |
268 | # include <linux/timer.h> /* time_after() */ | 268 | # include <linux/timer.h> /* time_after() */ |
269 | 269 | ||
270 | # ifdef CONFIG_BALANCED_IRQ_DEBUG | 270 | #ifdef CONFIG_BALANCED_IRQ_DEBUG |
271 | # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) | 271 | # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) |
272 | # define Dprintk(x...) do { TDprintk(x); } while (0) | 272 | # define Dprintk(x...) do { TDprintk(x); } while (0) |
273 | # else | 273 | # else |
@@ -275,10 +275,15 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
275 | # define Dprintk(x...) | 275 | # define Dprintk(x...) |
276 | # endif | 276 | # endif |
277 | 277 | ||
278 | |||
279 | #define IRQBALANCE_CHECK_ARCH -999 | 278 | #define IRQBALANCE_CHECK_ARCH -999 |
280 | static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; | 279 | #define MAX_BALANCED_IRQ_INTERVAL (5*HZ) |
281 | static int physical_balance = 0; | 280 | #define MIN_BALANCED_IRQ_INTERVAL (HZ/2) |
281 | #define BALANCED_IRQ_MORE_DELTA (HZ/10) | ||
282 | #define BALANCED_IRQ_LESS_DELTA (HZ) | ||
283 | |||
284 | static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH; | ||
285 | static int physical_balance __read_mostly; | ||
286 | static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL; | ||
282 | 287 | ||
283 | static struct irq_cpu_info { | 288 | static struct irq_cpu_info { |
284 | unsigned long * last_irq; | 289 | unsigned long * last_irq; |
@@ -297,12 +302,14 @@ static struct irq_cpu_info { | |||
297 | 302 | ||
298 | #define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) | 303 | #define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) |
299 | 304 | ||
300 | #define MAX_BALANCED_IRQ_INTERVAL (5*HZ) | 305 | static cpumask_t balance_irq_affinity[NR_IRQS] = { |
301 | #define MIN_BALANCED_IRQ_INTERVAL (HZ/2) | 306 | [0 ... NR_IRQS-1] = CPU_MASK_ALL |
302 | #define BALANCED_IRQ_MORE_DELTA (HZ/10) | 307 | }; |
303 | #define BALANCED_IRQ_LESS_DELTA (HZ) | ||
304 | 308 | ||
305 | static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; | 309 | void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) |
310 | { | ||
311 | balance_irq_affinity[irq] = mask; | ||
312 | } | ||
306 | 313 | ||
307 | static unsigned long move(int curr_cpu, cpumask_t allowed_mask, | 314 | static unsigned long move(int curr_cpu, cpumask_t allowed_mask, |
308 | unsigned long now, int direction) | 315 | unsigned long now, int direction) |
@@ -340,7 +347,7 @@ static inline void balance_irq(int cpu, int irq) | |||
340 | if (irqbalance_disabled) | 347 | if (irqbalance_disabled) |
341 | return; | 348 | return; |
342 | 349 | ||
343 | cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); | 350 | cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]); |
344 | new_cpu = move(cpu, allowed_mask, now, 1); | 351 | new_cpu = move(cpu, allowed_mask, now, 1); |
345 | if (cpu != new_cpu) { | 352 | if (cpu != new_cpu) { |
346 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); | 353 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); |
@@ -529,7 +536,9 @@ tryanotherirq: | |||
529 | } | 536 | } |
530 | } | 537 | } |
531 | 538 | ||
532 | cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); | 539 | cpus_and(allowed_mask, |
540 | cpu_online_map, | ||
541 | balance_irq_affinity[selected_irq]); | ||
533 | target_cpu_mask = cpumask_of_cpu(min_loaded); | 542 | target_cpu_mask = cpumask_of_cpu(min_loaded); |
534 | cpus_and(tmp, target_cpu_mask, allowed_mask); | 543 | cpus_and(tmp, target_cpu_mask, allowed_mask); |
535 | 544 | ||