lkml.org 
[lkml]   [2011]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 1/2] softirq: introduce loacal_bh_enable_force_wake()
    On Thu, Feb 03, 2011 at 06:17:39PM +0800, Yong Zhang wrote:
    > Maybe we can introduce another type of local_bh_enable() in which
    > waking up ksoftirqd is forced if needed.

    ---
    From: Yong Zhang <yong.zhang0@gmail.com>
    Subject: [PATCH 1/2] softirq: introduce loacal_bh_enable_force_wake()

    If there is pending softirq, don't handle it in the caller's
    context, invoke ksoftirqd directly instead.

    del_timer_sync() will be the first caller.

    Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    ---
    include/linux/bottom_half.h | 1 +
    kernel/softirq.c | 19 ++++++++++++++-----
    2 files changed, 15 insertions(+), 5 deletions(-)

    diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h
    index 27b1bcf..665d697 100644
    --- a/include/linux/bottom_half.h
    +++ b/include/linux/bottom_half.h
    @@ -5,5 +5,6 @@ extern void local_bh_disable(void);
    extern void _local_bh_enable(void);
    extern void local_bh_enable(void);
    extern void local_bh_enable_ip(unsigned long ip);
    +extern void local_bh_enable_force_wake(void);

    #endif /* _LINUX_BH_H */
    diff --git a/kernel/softirq.c b/kernel/softirq.c
    index 68eb5ef..5f224d4 100644
    --- a/kernel/softirq.c
    +++ b/kernel/softirq.c
    @@ -154,7 +154,7 @@ void _local_bh_enable(void)

    EXPORT_SYMBOL(_local_bh_enable);

    -static inline void _local_bh_enable_ip(unsigned long ip)
    +static inline void _local_bh_enable_ip(unsigned long ip, bool force_wake)
    {
    WARN_ON_ONCE(in_irq() || irqs_disabled());
    #ifdef CONFIG_TRACE_IRQFLAGS
    @@ -171,8 +171,12 @@ static inline void _local_bh_enable_ip(unsigned long ip)
    */
    sub_preempt_count(SOFTIRQ_DISABLE_OFFSET - 1);

    - if (unlikely(!in_interrupt() && local_softirq_pending()))
    - do_softirq();
    + if (unlikely(!in_interrupt() && local_softirq_pending())) {
    + if (!force_wake)
    + do_softirq();
    + else
    + wakeup_softirqd();
    + }

    dec_preempt_count();
    #ifdef CONFIG_TRACE_IRQFLAGS
    @@ -183,16 +187,21 @@ static inline void _local_bh_enable_ip(unsigned long ip)

    void local_bh_enable(void)
    {
    - _local_bh_enable_ip((unsigned long)__builtin_return_address(0));
    + _local_bh_enable_ip((unsigned long)__builtin_return_address(0), false);
    }
    EXPORT_SYMBOL(local_bh_enable);

    void local_bh_enable_ip(unsigned long ip)
    {
    - _local_bh_enable_ip(ip);
    + _local_bh_enable_ip(ip, false);
    }
    EXPORT_SYMBOL(local_bh_enable_ip);

    +void local_bh_enable_force_wake(void)
    +{
    + _local_bh_enable_ip((unsigned long)__builtin_return_address(0), true);
    +}
    +EXPORT_SYMBOL(local_bh_enable_force_wake);
    /*
    * We restart softirq processing MAX_SOFTIRQ_RESTART times,
    * and we fall back to softirqd after that.
    --
    1.7.1


    \
     
     \ /
      Last update: 2011-02-03 12:53    [W:0.027 / U:1.692 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site