lkml.org 
[lkml]   [2022]   [Nov]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v5 3/3] softirq: defer softirq processing to ksoftirqd if CPU is busy with RT
    From
    From: Pavankumar Kondeti <pkondeti@codeaurora.org>

    Defer the softirq processing to ksoftirqd if a RT task is
    running or queued on the current CPU. This complements the RT
    task placement algorithm which tries to find a CPU that is not
    currently busy with softirqs.

    Currently NET_TX, NET_RX, BLOCK and IRQ_POLL softirqs are only
    deferred as they can potentially run for long time.

    Additionally, this patch stubs out ksoftirqd_running() logic,
    in the CONFIG_RT_SOFTIRQ_AWARE_SCHED case, as deferring
    potentially long-running softirqs will cause the logic to not
    process shorter-running softirqs immediately. By stubbing it out
    the potentially long running softirqs are deferred, but the
    shorter running ones can still run immediately.

    This patch includes folded-in fixes by:
    Lingutla Chandrasekhar <clingutla@codeaurora.org>
    Satya Durga Srinivasu Prabhala <satyap@codeaurora.org>
    J. Avila <elavila@google.com>

    Cc: John Dias <joaodias@google.com>
    Cc: Connor O'Brien <connoro@google.com>
    Cc: Rick Yiu <rickyiu@google.com>
    Cc: John Kacur <jkacur@redhat.com>
    Cc: Qais Yousef <qyousef@google.com>
    Cc: Chris Redpath <chris.redpath@arm.com>
    Cc: Abhijeet Dharmapurikar <adharmap@quicinc.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Juri Lelli <juri.lelli@redhat.com>
    Cc: Vincent Guittot <vincent.guittot@linaro.org>
    Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Heiko Carstens <hca@linux.ibm.com>
    Cc: Vasily Gorbik <gor@linux.ibm.com>
    Cc: Joel Fernandes <joel@joelfernandes.org>
    Cc: Alexander Gordeev <agordeev@linux.ibm.com>
    Cc: kernel-team@android.com
    Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
    [satyap@codeaurora.org: trivial merge conflict resolution.]
    Signed-off-by: Satya Durga Srinivasu Prabhala <satyap@codeaurora.org>
    [elavila: Port to mainline, squash with bugfix]
    Signed-off-by: J. Avila <elavila@google.com>
    [jstultz: Rebase to linus/HEAD, minor rearranging of code,
    included bug fix Reported-by: Qais Yousef <qais.yousef@arm.com> ]
    Signed-off-by: John Stultz <jstultz@google.com>
    ---
    v4:
    * Fix commit message to accurately note long-running softirqs
    (suggested by Qais)
    * Switch to using rt_task(current) (suggested by Qais)
    v5:
    * Switch to using CONFIG_RT_SOFTIRQ_AWARE_SCHED (suggested by
    Joel Fernandes <joel@joelfernandes.org>)
    ---
    kernel/softirq.c | 29 +++++++++++++++++++++++++++--
    1 file changed, 27 insertions(+), 2 deletions(-)

    diff --git a/kernel/softirq.c b/kernel/softirq.c
    index dd92ce8f771b..5db2afd0be68 100644
    --- a/kernel/softirq.c
    +++ b/kernel/softirq.c
    @@ -95,6 +95,7 @@ static void wakeup_softirqd(void)
    wake_up_process(tsk);
    }

    +#ifndef CONFIG_RT_SOFTIRQ_AWARE_SCHED
    /*
    * If ksoftirqd is scheduled, we do not want to process pending softirqs
    * right now. Let ksoftirqd handle this at its own rate, to get fairness,
    @@ -109,6 +110,9 @@ static bool ksoftirqd_running(unsigned long pending)
    return false;
    return tsk && task_is_running(tsk) && !__kthread_should_park(tsk);
    }
    +#else
    +#define ksoftirqd_running(pending) (false)
    +#endif /* CONFIG_RT_SOFTIRQ_AWARE_SCHED */

    #ifdef CONFIG_TRACE_IRQFLAGS
    DEFINE_PER_CPU(int, hardirqs_enabled);
    @@ -540,6 +544,21 @@ static inline bool lockdep_softirq_start(void) { return false; }
    static inline void lockdep_softirq_end(bool in_hardirq) { }
    #endif

    +#ifdef CONFIG_RT_SOFTIRQ_AWARE_SCHED
    +static __u32 softirq_deferred_for_rt(__u32 *pending)
    +{
    + __u32 deferred = 0;
    +
    + if (rt_task(current)) {
    + deferred = *pending & LONG_SOFTIRQ_MASK;
    + *pending &= ~LONG_SOFTIRQ_MASK;
    + }
    + return deferred;
    +}
    +#else
    +#define softirq_deferred_for_rt(x) (0)
    +#endif
    +
    asmlinkage __visible void __softirq_entry __do_softirq(void)
    {
    unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
    @@ -547,6 +566,7 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
    int max_restart = MAX_SOFTIRQ_RESTART;
    struct softirq_action *h;
    bool in_hardirq;
    + __u32 deferred;
    __u32 pending;
    int softirq_bit;

    @@ -558,14 +578,16 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
    current->flags &= ~PF_MEMALLOC;

    pending = local_softirq_pending();
    + deferred = softirq_deferred_for_rt(&pending);

    softirq_handle_begin();
    +
    in_hardirq = lockdep_softirq_start();
    account_softirq_enter(current);

    restart:
    /* Reset the pending bitmask before enabling irqs */
    - set_softirq_pending(0);
    + set_softirq_pending(deferred);
    set_active_softirqs(pending);

    local_irq_enable();
    @@ -604,13 +626,16 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
    local_irq_disable();

    pending = local_softirq_pending();
    + deferred = softirq_deferred_for_rt(&pending);
    +
    if (pending) {
    if (time_before(jiffies, end) && !need_resched() &&
    --max_restart)
    goto restart;
    + }

    + if (pending | deferred)
    wakeup_softirqd();
    - }

    account_softirq_exit(current);
    lockdep_softirq_end(in_hardirq);
    --
    2.38.1.431.g37b22c650d-goog
    \
     
     \ /
      Last update: 2022-11-16 09:00    [W:2.980 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site