aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorZhang Yanmin <yanmin.zhang@intel.com>2006-06-23 05:04:22 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-23 10:42:57 -0400
commit1b61b910e99059abdd54c93aa70e84e076e33d16 (patch)
treefe2cd431dc39521a0f2d30e22c9bd3eb3e1bc317 /arch/i386
parentafa024c3dbccf026e45121f4b9de54cda48edbea (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')
-rw-r--r--arch/i386/kernel/io_apic.c31
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
280static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; 279#define MAX_BALANCED_IRQ_INTERVAL (5*HZ)
281static 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
284static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH;
285static int physical_balance __read_mostly;
286static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL;
282 287
283static struct irq_cpu_info { 288static 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) 305static 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
305static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; 309void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
310{
311 balance_irq_affinity[irq] = mask;
312}
306 313
307static unsigned long move(int curr_cpu, cpumask_t allowed_mask, 314static 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