aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/io_apic.c31
-rw-r--r--include/linux/irq.h8
-rw-r--r--kernel/irq/proc.c3
3 files changed, 31 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
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 42c9cd562860..e8a07e75e4fb 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -164,6 +164,14 @@ static inline void set_irq_info(int irq, cpumask_t mask)
164 164
165#endif // CONFIG_SMP 165#endif // CONFIG_SMP
166 166
167#ifdef CONFIG_IRQBALANCE
168extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask);
169#else
170static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
171{
172}
173#endif
174
167extern int no_irq_affinity; 175extern int no_irq_affinity;
168extern int noirqdebug_setup(char *str); 176extern int noirqdebug_setup(char *str);
169 177
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index d03b5eef8ce0..afacd6f585fa 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -24,6 +24,8 @@ static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
24#ifdef CONFIG_GENERIC_PENDING_IRQ 24#ifdef CONFIG_GENERIC_PENDING_IRQ
25void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) 25void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val)
26{ 26{
27 set_balance_irq_affinity(irq, mask_val);
28
27 /* 29 /*
28 * Save these away for later use. Re-progam when the 30 * Save these away for later use. Re-progam when the
29 * interrupt is pending 31 * interrupt is pending
@@ -33,6 +35,7 @@ void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val)
33#else 35#else
34void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) 36void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val)
35{ 37{
38 set_balance_irq_affinity(irq, mask_val);
36 irq_affinity[irq] = mask_val; 39 irq_affinity[irq] = mask_val;
37 irq_desc[irq].handler->set_affinity(irq, mask_val); 40 irq_desc[irq].handler->set_affinity(irq, mask_val);
38} 41}