lkml.org 
[lkml]   [2018]   [Jan]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC 2/6] softirq: Introduce mask for __do_softirq()
    Date
    __do_softirq() serves all pending softirqs.
    As we need to separate softirqs by different groups, we need to serve
    softirqs from one group and deffer softirqs from the other.
    Change __do_softirq() so it'll have a mask of softirqs it needs to
    serve instead of servicing all pending softirqs.

    Signed-off-by: Dmitry Safonov <dima@arista.com>
    ---
    include/linux/interrupt.h | 8 ++++----
    kernel/softirq.c | 27 ++++++++++++++-------------
    2 files changed, 18 insertions(+), 17 deletions(-)

    diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
    index 5bb6b435f0bb..2ea09896bd6e 100644
    --- a/include/linux/interrupt.h
    +++ b/include/linux/interrupt.h
    @@ -490,14 +490,14 @@ struct softirq_action
    };

    asmlinkage void do_softirq(void);
    -asmlinkage void __do_softirq(void);
    +asmlinkage void __do_softirq(__u32 mask);

    #ifdef __ARCH_HAS_DO_SOFTIRQ
    -void do_softirq_own_stack(void);
    +void do_softirq_own_stack(__u32 mask);
    #else
    -static inline void do_softirq_own_stack(void)
    +static inline void do_softirq_own_stack(__u32 mask)
    {
    - __do_softirq();
    + __do_softirq(mask);
    }
    #endif

    diff --git a/kernel/softirq.c b/kernel/softirq.c
    index c9aecdd57107..ca8c3db4570d 100644
    --- a/kernel/softirq.c
    +++ b/kernel/softirq.c
    @@ -240,7 +240,7 @@ static inline bool lockdep_softirq_start(void) { return false; }
    static inline void lockdep_softirq_end(bool in_hardirq) { }
    #endif

    -asmlinkage __visible void __softirq_entry __do_softirq(void)
    +asmlinkage __visible void __softirq_entry __do_softirq(__u32 mask)
    {
    unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
    unsigned long old_flags = current->flags;
    @@ -265,7 +265,8 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)

    restart:
    /* Reset the pending bitmask before enabling irqs */
    - set_softirq_pending(0);
    + set_softirq_pending(pending & ~mask);
    + pending &= mask;

    local_irq_enable();

    @@ -299,7 +300,7 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
    local_irq_disable();

    pending = local_softirq_pending();
    - if (pending) {
    + if (pending & mask) {
    if (time_before(jiffies, end) && !need_resched() &&
    --max_restart)
    goto restart;
    @@ -316,18 +317,16 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)

    asmlinkage __visible void do_softirq(void)
    {
    - __u32 pending;
    + __u32 pending = local_softirq_pending();
    unsigned long flags;

    - if (in_interrupt())
    + if (in_interrupt() || !pending)
    return;

    local_irq_save(flags);

    - pending = local_softirq_pending();
    -
    - if (pending && !ksoftirqd_running())
    - do_softirq_own_stack();
    + if (!ksoftirqd_running())
    + do_softirq_own_stack(pending);

    local_irq_restore(flags);
    }
    @@ -353,7 +352,9 @@ void irq_enter(void)

    static inline void invoke_softirq(void)
    {
    - if (ksoftirqd_running())
    + __u32 pending = local_softirq_pending();
    +
    + if (!pending || !ksoftirqd_running())
    return;

    if (!force_irqthreads) {
    @@ -363,14 +364,14 @@ static inline void invoke_softirq(void)
    * it is the irq stack, because it should be near empty
    * at this stage.
    */
    - __do_softirq();
    + __do_softirq(pending);
    #else
    /*
    * Otherwise, irq_exit() is called on the task stack that can
    * be potentially deep already. So call softirq in its own stack
    * to prevent from any overrun.
    */
    - do_softirq_own_stack();
    + do_softirq_own_stack(pending);
    #endif
    } else {
    wakeup_softirqd();
    @@ -679,7 +680,7 @@ static void run_ksoftirqd(unsigned int cpu)
    * We can safely run softirq on inline stack, as we are not deep
    * in the task stack here.
    */
    - __do_softirq();
    + __do_softirq(~0);
    local_irq_enable();
    cond_resched_rcu_qs();
    return;
    --
    2.13.6
    \
     
     \ /
      Last update: 2018-01-18 17:14    [W:2.472 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site