lkml.org 
[lkml]   [2004]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [linux-audio-dev] Re: [announce] [patch] Voluntary Kernel Preemption Patch
    Ingo Molnar wrote:
    >>below i've also attached a softirq.c patch against 2.6.8-rc2 that does
    >>unconditional deferring. (this patch is of course not intended to be
    >>merged upstream as-is, since normally we want to process softirqs
    >>right after the irq context.)
    >
    >
    > i've got a more complete patch against vanilla 2.6.8-rc2:
    >
    > http://redhat.com/~mingo/voluntary-preempt/defer-softirqs-2.6.8-rc2-A2
    >
    > which introduces the following tunable:
    >
    > /proc/sys/kernel/defer_softirqs (default: 0)
    >
    > this, if enabled, causes all softirqs to be processed within ksoftirqd,
    > and it also breaks out of the softirq loop if preemption of ksoftirqd
    > has been triggered by a higher-prio task.
    >
    > I've also added this additional break-out to the -H6 patch of
    > voluntary-preempt:
    >
    > http://redhat.com/~mingo/voluntary-preempt/voluntary-preempt-2.6.8-rc2-H6
    >
    > it's enabled by default.
    >

    What do you think about deferring softirqs just while in critical
    sections?

    I'm not sure how well this works, and it is CONFIG_PREEMPT only
    but in theory it should prevent unbounded softirqs while under
    locks without taking the performance hit of doing the context
    switch.



    ---

    linux-2.6-npiggin/include/asm-i386/hardirq.h | 8 ++++++--
    linux-2.6-npiggin/include/linux/preempt.h | 6 +-----
    linux-2.6-npiggin/kernel/sched.c | 13 +++++++++++--
    linux-2.6-npiggin/kernel/softirq.c | 4 ++--
    4 files changed, 20 insertions(+), 11 deletions(-)

    diff -puN kernel/softirq.c~lat-softirq kernel/softirq.c
    --- linux-2.6/kernel/softirq.c~lat-softirq 2004-07-17 00:32:52.000000000 +1000
    +++ linux-2.6-npiggin/kernel/softirq.c 2004-07-17 00:32:52.000000000 +1000
    @@ -68,7 +68,7 @@ static inline void wakeup_softirqd(void)
    * 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
    +#define MAX_SOFTIRQ_RESTART 4

    asmlinkage void __do_softirq(void)
    {
    @@ -322,7 +322,7 @@ void __init softirq_init(void)

    static int ksoftirqd(void * __bind_cpu)
    {
    - set_user_nice(current, 19);
    + set_user_nice(current, 10);
    current->flags |= PF_NOFREEZE;

    set_current_state(TASK_INTERRUPTIBLE);
    diff -puN include/asm-i386/hardirq.h~lat-softirq include/asm-i386/hardirq.h
    --- linux-2.6/include/asm-i386/hardirq.h~lat-softirq 2004-07-17 00:32:52.000000000 +1000
    +++ linux-2.6-npiggin/include/asm-i386/hardirq.h 2004-07-17 00:32:52.000000000 +1000
    @@ -80,17 +80,21 @@ typedef struct {
    # include <linux/smp_lock.h>
    # define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
    # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
    +#define irq_exit() \
    +do { \
    + preempt_count() -= IRQ_EXIT_OFFSET; \
    + preempt_enable_no_resched(); /* This will catch the softirq */ \
    +} while (0)
    #else
    # define in_atomic() (preempt_count() != 0)
    # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
    -#endif
    #define irq_exit() \
    do { \
    preempt_count() -= IRQ_EXIT_OFFSET; \
    if (!in_interrupt() && softirq_pending(smp_processor_id())) \
    do_softirq(); \
    - preempt_enable_no_resched(); \
    } while (0)
    +#endif

    #ifndef CONFIG_SMP
    # define synchronize_irq(irq) barrier()
    diff -puN include/linux/preempt.h~lat-softirq include/linux/preempt.h
    --- linux-2.6/include/linux/preempt.h~lat-softirq 2004-07-17 00:32:52.000000000 +1000
    +++ linux-2.6-npiggin/include/linux/preempt.h 2004-07-17 00:32:52.000000000 +1000
    @@ -16,12 +16,8 @@ do { \
    preempt_count()++; \
    } while (0)

    -#define dec_preempt_count() \
    -do { \
    - preempt_count()--; \
    -} while (0)
    -
    #ifdef CONFIG_PREEMPT
    +void dec_preempt_count(void);

    asmlinkage void preempt_schedule(void);

    diff -puN kernel/sched.c~lat-softirq kernel/sched.c
    --- linux-2.6/kernel/sched.c~lat-softirq 2004-07-17 00:32:52.000000000 +1000
    +++ linux-2.6-npiggin/kernel/sched.c 2004-07-17 00:32:52.000000000 +1000
    @@ -3968,8 +3968,16 @@ void __might_sleep(char *file, int line)
    EXPORT_SYMBOL(__might_sleep);
    #endif

    +#ifdef CONFIG_PREEMPT
    +void dec_preempt_count(void)
    +{
    + if (unlikely(preempt_count() == 1 &&
    + softirq_pending(smp_processor_id())))
    + do_softirq();
    + preempt_count()--;
    +}

    -#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)
    +#ifdef CONFIG_SMP
    /*
    * This could be a long-held lock. If another CPU holds it for a long time,
    * and that CPU is not asked to reschedule then *this* CPU will spin on the
    @@ -4012,4 +4020,5 @@ void __sched __preempt_write_lock(rwlock
    }

    EXPORT_SYMBOL(__preempt_write_lock);
    -#endif /* defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) */
    +#endif /* CONFIG_SMP */
    +#endif /* CONFIG_PREEMPT */
    _
    \
     
     \ /
      Last update: 2005-03-22 14:04    [W:3.595 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site