diff options
-rw-r--r-- | arch/i386/kernel/io_apic.c | 31 | ||||
-rw-r--r-- | include/linux/irq.h | 8 | ||||
-rw-r--r-- | kernel/irq/proc.c | 3 |
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 |
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 | ||
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 | ||
168 | extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask); | ||
169 | #else | ||
170 | static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) | ||
171 | { | ||
172 | } | ||
173 | #endif | ||
174 | |||
167 | extern int no_irq_affinity; | 175 | extern int no_irq_affinity; |
168 | extern int noirqdebug_setup(char *str); | 176 | extern 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 |
25 | void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) | 25 | void 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 |
34 | void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) | 36 | void 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 | } |