- 论坛徽章:
- 0
|
以下是arch/i386/kernel/io_apic.c的补丁。在1个NIC,2个CPU和 2个NIC, 2个CPU上都平衡的很好。多个CPU也应该可以很好地平衡。但是我没有测试。
- --- io_apic.c 2007-07-13 13:24:57.000000000 +0800
- +++ io_apic.c 2007-07-13 14:24:15.000000000 +0800
- @@ -46,6 +46,23 @@
- #include "io_ports.h"
- +
- +#define SEEKER_BALANCE_NETWORK_IRQ
- +/* network irq balancer testing version, by seeker. 2007.07.13
- + * tested on 1 NIC with 2 cpus, 2 NICs with 2 cpus. it should be working on more NICs and more CPUs
- + *
- + * tested on
- + * Linux yelinux 2.6.13-15-johnye #16 SMP Thu Jul 12 13:05:37 CST 2007 i686 athlon i386 GNU/Linux
- + *
- + * you are welcome to do more testing on a linux box with 3 or more cpus,
- + *
- + * you should apply this patch to testing server instead of to production server.
- + *
- + * user mode irqbalance is not needed. please don't run it on kernel with this patch.
- + *
- + */
- +
- +
- int (*ioapic_renumber_irq)(int ioapic, int irq);
- atomic_t irq_mis_count;
- @@ -294,6 +311,16 @@
- static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL;
- +#ifdef SEEKER_BALANCE_NETWORK_IRQ
- +struct {
- + char irq;
- + unsigned char count;
- +} cpuinfo[NR_CPUS];
- +
- +unsigned char wait[NR_IRQS];
- +unsigned char isnet[NR_IRQS];
- +#endif
- +
- static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
- unsigned long now, int direction)
- {
- @@ -336,6 +363,20 @@
- irq_desc_t *desc = irq_desc + irq;
- unsigned long flags;
- +#ifdef SEEKER_BALANCE_NETWORK_IRQ
- + if(isnet[irq]) {
- + if(cpuinfo[new_cpu].count > 0) {
- + //printk("-------- .\n");
- + return;
- + }
- + //printk("ye1: old %d new %d: LAST_CPU_IRQ(new_cpu, irq) %d\n", cpu, new_cpu, LAST_CPU_IRQ(new_cpu, irq));
- + cpuinfo[cpu].irq = 0; //old cpu
- + cpuinfo[cpu].count = 0;
- + cpuinfo[new_cpu].irq = irq;
- + cpuinfo[new_cpu].count++;
- + }
- + //printk("PEND: irq %d mask %p\n", irq, cpumask_of_cpu(new_cpu));
- +#endif
- spin_lock_irqsave(&desc->lock, flags);
- pending_irq_balance_cpumask[irq] = cpumask_of_cpu(new_cpu);
- spin_unlock_irqrestore(&desc->lock, flags);
- @@ -354,6 +395,14 @@
- if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) <
- useful_load_threshold)
- continue;
- +
- +#ifdef SEEKER_BALANCE_NETWORK_IRQ
- + if(isnet[j]) {
- + printk("not for net irq %d...\n", j);
- + continue;
- + }
- +#endif
- +
- balance_irq(i, j);
- }
- }
- @@ -362,6 +411,42 @@
- return;
- }
- +
- +#ifdef SEEKER_BALANCE_NETWORK_IRQ
- +void net_balance(int irq)
- +{
- +int cpu, ncpus;
- +unsigned long max;
- +int max_cpu;
- +
- + //if(++wait[irq] < 32) return;
- + wait[irq] = 0;
- +
- + if(!isnet[irq]) return;
- +
- + max = ncpus = 0;
- + max_cpu = -1;
- + for(cpu = 0; cpu < NR_CPUS; cpu++) {
- + if(!cpu_online(cpu)) continue;
- + ncpus++;
- + //printk("YE cpu %d irq %d ", cpu, LAST_CPU_IRQ(cpu, irq));
- + //printk("IRQ_DELTA(irq %d cpu %d) %d\n", irq, cpu, IRQ_DELTA(cpu, irq));
- + //
- + if(max < LAST_CPU_IRQ(cpu, irq)) {
- + max = LAST_CPU_IRQ(cpu, irq);
- + max_cpu = cpu;
- + }
- + }
- + if(ncpus < 2) return;
- +
- + //printk("YE irq %d max_cpu %d. irq %d count %d\n", irq, max_cpu, cpuinfo[max_cpu].irq, cpuinfo[max_cpu].count);
- + if(max_cpu >= 0) {
- + balance_irq(max_cpu, irq);
- + }
- +}
- +#endif
- +
- +
- static void do_irq_balance(void)
- {
- int i, j;
- @@ -376,6 +461,13 @@
- unsigned long imbalance = 0;
- cpumask_t allowed_mask, target_cpu_mask, tmp;
- +
- +#ifdef SEEKER_BALANCE_NETWORK_IRQ
- + if(irqbalance_disabled)
- + printk("SEEKER: irqblance_disabled %d physical_balance %d, %d\n", irqbalance_disabled, physical_balance, NO_BALANCE_IRQ);
- + //irqbalance_disabled = 0; //JOHNYE
- +#endif
- +
- for (i = 0; i < NR_CPUS; i++) {
- int package_index;
- CPU_IRQ(i) = 0;
- @@ -387,6 +479,14 @@
- /* Is this an active IRQ? */
- if (!irq_desc[j].action)
- continue;
- +
- +#ifdef SEEKER_BALANCE_NETWORK_IRQ
- + if(!strncmp(irq_desc[j].action->name, "eth", 3)) { //network
- + isnet[j] = 1;
- + net_balance(j);
- + }
- +#endif
- +
- if ( package_index == i )
- IRQ_DELTA(package_index,j) = 0;
- /* Determine the total count per processor per IRQ */
复制代码 |
|