Hi, While testing the SMP performance of iptables with a lot of rules on a mips based cpu, I found that the SMP performance was 40% lower on 2 cpus than 1 cpu.
There is a number of reasons for this the primary being that the rules were bigger than the shared L2 cache, little enough can be done about this. The second is that interrupts are on every mips port I bothered checking are only delivered on cpu 0 ( this is really pathetic ). See the code that prints /proc/interrupts in arch/mips/kernel/irq.c int get_irq_list(char *buf) { struct irqaction * action; char *p = buf; int i; p += sprintf(p, " "); for (i=0; i < 1 /*smp_num_cpus*/; i++) Need I say more..... As softirqs are usually bound to the same cpu that start the softirqs softirqs performs really really badly, also the fact that the softirq.c code checks in_interrupt on entry means that it frequently does a quick exit. I also will be providing a patch I developed to the developers of a mips based system on chip which distributes the irqs over all cpus using 2 polices even interrupts to cpu 0 odd interrupts to cpu 1 or leaving the interrupts enter in all cpus & only call do_IRQ on the cpu with the lowest local_irq_count & local_bh_count this should cause softirqs to perform will on this system anyway. I've provided a small patch to irq.c which fixes /proc/interrupts in 2.4.18 mips32 hopefully somebody will be kind enough to fix up the 64 bit & the latest stuff in mips64 & the latest oss.sgi.com cvs trees. --- linux.orig/arch/mips/kernel/irq.c Sun Sep 9 18:43:01 2001 +++ linux/arch/mips/kernel/irq.c Mon May 13 10:34:15 2002 @@ -71,13 +71,13 @@ int get_irq_list(char *buf) { + int i, j; struct irqaction * action; char *p = buf; - int i; p += sprintf(p, " "); - for (i=0; i < 1 /*smp_num_cpus*/; i++) - p += sprintf(p, "CPU%d ", i); + for (j=0; j<smp_num_cpus; j++) + p += sprintf(p, "CPU%d ",j); *p++ = '\n'; for (i = 0 ; i < NR_IRQS ; i++) { @@ -85,7 +85,13 @@ if (!action) continue; p += sprintf(p, "%3d: ",i); +#ifndef CONFIG_SMP p += sprintf(p, "%10u ", kstat_irqs(i)); +#else + for (j = 0; j < smp_num_cpus; j++) + p += sprintf(p, "%10u ", + kstat.irqs[cpu_logical_map(j)][i]); +#endif p += sprintf(p, " %14s", irq_desc[i].handler->typename); p += sprintf(p, " %s", action->name); @@ -93,7 +99,7 @@ p += sprintf(p, ", %s", action->name); *p++ = '\n'; } - p += sprintf(p, "ERR: %10lu\n", irq_err_count); + p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); return p - buf; } I also provide a small patch for softirq.c which makes sure the the softirqs stay running if in cpu_idle & no reschedule is pending. This improves softirq.c performance a small bit as it usually exits after calling each softirq once rather than staying in the loop if it has nothing better to do. --- linux.old/kernel/softirq.c Tue Jan 15 04:13:43 2002 +++ linux.new/kernel/softirq.c Thu May 9 12:36:46 2002 @@ -95,7 +95,8 @@ local_irq_disable(); pending = softirq_pending(cpu); - if (pending & mask) { + if ((pending && current==idle_task(cpu) && !current->need_resched ) + || (pending & mask) ) { mask &= ~pending; goto restart; } diff -u -r linux.old/include/linux/sched.h linux.new/include/linux/sched.h --- linux.old/include/linux/sched.h Thu May 9 18:08:42 2002 +++ linux.new/include/linux/sched.h Thu May 9 10:30:34 2002 @@ -936,6 +936,19 @@ return res; } +#ifdef CONFIG_SMP + +#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)]) +#define can_schedule(p,cpu) \ + ((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu)) + +#else + +#define idle_task(cpu) (&init_task) +#define can_schedule(p,cpu) (1) + +#endif + #endif /* __KERNEL__ */ #endif diff -u -r linux.old/kernel/sched.c linux.new/kernel/sched.c --- linux.old/kernel/sched.c Wed May 1 10:40:26 2002 +++ linux.new/kernel/sched.c Thu May 9 10:30:26 2002 @@ -112,18 +112,7 @@ struct kernel_stat kstat; extern struct task_struct *child_reaper; -#ifdef CONFIG_SMP -#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)]) -#define can_schedule(p,cpu) \ - ((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu)) - -#else - -#define idle_task(cpu) (&init_task) -#define can_schedule(p,cpu) (1) - -#endif void scheduling_functions_start_here(void) { } Also find the patches sent as attachments. ===== D.J. Barrow Linux kernel developer eMail: [EMAIL PROTECTED] Home: +353-22-47196. Work: +353-91-758353 __________________________________________________ Do You Yahoo!? LAUNCH - Your Yahoo! Music Experience http://launch.yahoo.com
softirq_fix.diff
Description: softirq_fix.diff
mips32_irq.c_fix.diff
Description: mips32_irq.c_fix.diff