lkml.org 
[lkml]   [2001]   [May]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch] softirq-2.4.5-B0

    On Sat, 26 May 2001, David S. Miller wrote:

    > And looking at the x86 code, I don't even understand how your fixes
    > can make a difference, what about the do_softirq() call in
    > arch/i386/kernel/irq.c:do_IRQ()??? [...]

    [you are right, it's a brain fart on my part. doh. i guess i was too happy
    having fixed the longstanding latency problem.]

    the TCP latency issues and the missed softirq execution bug is still
    there, but for a slightly different reason.

    the bug/misbehavior causing bad latencies turned out to be the following:
    if a hardirq triggers a softirq, but syscall-level code on the same CPU
    disabled local bhs via local_bh_disable(), then we 'miss' the execution of
    the softirq, until the next IRQ. (or next direct call to do_softirq()).

    the attached softirq-2.4.5-B0 patch fixes this problem by calling
    do_softirq() from local_bh_enable() [if the bh count is 0, to avoid
    recursion]. This slightly changes local_bh_enable() semantics: calling
    do_softirq() has the side-effect of disabling/enabling interrupts, so code
    that used local_bh_enable while interrupts are disabled (and depended on
    them staying disabled) will break. I checked all code that uses
    local_bh_enable() via a debugging check, and the only (harmless) violation
    of this new rule is machine_restart() in the x86 tree.

    Yesterday's patches fix this problem too, but only as a lucky side-effect,
    and only in the idle-poll case. 2.4.5 + softirq-2.4.5-B0 TCP latency is
    down from a fluctuating 300-400 microseconds to a stable 109 microseconds.

    Ingo
    --- linux/kernel/softirq.c.orig Sun May 27 20:57:36 2001
    +++ linux/kernel/softirq.c Sun May 27 20:57:52 2001
    @@ -87,7 +87,7 @@
    goto retry;
    }

    - local_bh_enable();
    + __local_bh_enable();

    /* Leave with locally disabled hard irqs. It is critical to close
    * window for infinite recursion, while we help local bh count,
    --- linux/include/asm-i386/softirq.h.orig Sun May 27 20:56:58 2001
    +++ linux/include/asm-i386/softirq.h Sun May 27 20:58:15 2001
    @@ -5,10 +5,12 @@
    #include <asm/hardirq.h>

    #define cpu_bh_disable(cpu) do { local_bh_count(cpu)++; barrier(); } while (0)
    -#define cpu_bh_enable(cpu) do { barrier(); local_bh_count(cpu)--; } while (0)
    +#define __cpu_bh_enable(cpu) do { barrier(); local_bh_count(cpu)--; } while (0)
    +extern void cpu_bh_enable (unsigned int cpu);

    #define local_bh_disable() cpu_bh_disable(smp_processor_id())
    #define local_bh_enable() cpu_bh_enable(smp_processor_id())
    +#define __local_bh_enable() __cpu_bh_enable(smp_processor_id())

    #define in_softirq() (local_bh_count(smp_processor_id()) != 0)

    --- linux/arch/i386/kernel/irq.c.orig Sun May 27 20:55:08 2001
    +++ linux/arch/i386/kernel/irq.c Sun May 27 20:56:45 2001
    @@ -628,6 +628,19 @@
    return 1;
    }

    +/*
    + * A bh-atomic section might have blocked the execution of softirqs.
    + * re-run them if appropriate.
    + */
    +void cpu_bh_enable (unsigned int cpu)
    +{
    + if (!--local_bh_count(cpu) &&
    + (softirq_active(cpu) & softirq_mask(cpu))) {
    + do_softirq();
    + __sti();
    + }
    +}
    +
    /**
    * request_irq - allocate an interrupt line
    * @irq: Interrupt line to allocate
    \
     
     \ /
      Last update: 2005-03-22 12:54    [W:2.894 / U:0.468 seconds]
    ©2003-2014 Jasper Spaans. hosted at Digital Ocean