Re: major network performance difference between 2.4 and 2.6.2-rc2

Andrew Morton
2004-02-04T21:24:27Z

"David S. Miller" <davem@redhat.com> wrote:
>
> On Wed, 4 Feb 2004 12:54:44 -0800
> Andrew Morton <akpm@osdl.org> wrote:
>
> > Jim Faulkner <jfaulkne@ccs.neu.edu> wrote:
> > > PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
> > > 3 root 35 19 0 0 0 S 45.9 0.0 0:46.98 ksoftirqd/0
> > > 6 root 5 -10 0 0 0 S 43.3 0.0 1:56.63 events/0
> > > 12008 dogshu 15 0 4800 2356 3828 S 5.3 0.2 0:05.98 proftpd
> > > 12 root 15 0 0 0 0 S 0.3 0.0 0:00.41 pdflush
> > > 9778 root 16 0 5888 1724 5516 R 0.3 0.2 0:00.12 sshd
> > >
> > > the load before that network transfer was 0.01, and the load after the
> > > network transfer was 1.45.
> >
> > Could be a networking problem, but boy that's a lot of CPU time.
>
> Andrew maybe something bolixed in the MAX_SOFTIRQ_RESTART stuff
> we put into kernel/softirq.c? Just a guess...

Might be. Jim, does a `patch -p1 -R' of the below help things?

diff -Nru a/kernel/softirq.c b/kernel/softirq.c
--- a/kernel/softirq.c Wed Feb 4 13:20:39 2004
+++ b/kernel/softirq.c Wed Feb 4 13:20:39 2004
@@ -57,11 +57,22 @@
wake_up_process(tsk);
}

+/*
+ * We restart softirq processing MAX_SOFTIRQ_RESTART times,
+ * and we fall back to softirqd after that.
+ *
+ * This number has been established via experimentation.
+ * The two things to balance is latency against fairness -
+ * we want to handle softirqs as soon as possible, but they
+ * should not be able to lock up the box.
+ */
+#define MAX_SOFTIRQ_RESTART 10
+
asmlinkage void do_softirq(void)
{
+ int max_restart = MAX_SOFTIRQ_RESTART;
__u32 pending;
unsigned long flags;
- __u32 mask;

if (in_interrupt())
return;
@@ -73,7 +84,6 @@
if (pending) {
struct softirq_action *h;

- mask = ~pending;
local_bh_disable();
restart:
/* Reset the pending bitmask before enabling irqs */
@@ -93,10 +103,8 @@
local_irq_disable();

pending = local_softirq_pending();
- if (pending & mask) {
- mask &= ~pending;
+ if (pending && --max_restart)
goto restart;
- }
if (pending)
wakeup_softirqd();
__local_bh_enable();