ANDROID: softirq: defer softirq processing to ksoftirqd if CPU is busy with RT
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> Link: https://lore.kernel.org/lkml/20221116075929.453876-4-jstultz@google.com/ [jstultz: Had to rework this previous cherry-pick to android15-6.6 incorrectly re-added the ksoftirqd_running logic which was previously removed, and resulted in build issues for the !CONFIG_RT_SOFTIRQ_AWARE_SCHED case] Signed-off-by: John Stultz <jstultz@google.com> Change-Id: I626250ff25d2915e72b8758e9d00ceac6a182df1 Bug: 168521633 Bug: 332627282 --- 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>)
This commit is contained in:
committed by
Treehugger Robot
parent
01603b5411
commit
0312436e3f
+24
-3
@@ -526,6 +526,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
|
||||
|
||||
static void handle_softirqs(bool ksirqd)
|
||||
{
|
||||
unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
|
||||
@@ -533,6 +548,7 @@ static void handle_softirqs(bool ksirqd)
|
||||
int max_restart = MAX_SOFTIRQ_RESTART;
|
||||
struct softirq_action *h;
|
||||
bool in_hardirq;
|
||||
__u32 deferred;
|
||||
__u32 pending;
|
||||
int softirq_bit;
|
||||
|
||||
@@ -544,14 +560,16 @@ static void handle_softirqs(bool ksirqd)
|
||||
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();
|
||||
@@ -589,14 +607,17 @@ restart:
|
||||
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;
|
||||
|
||||
wakeup_softirqd();
|
||||
}
|
||||
|
||||
if (pending | deferred)
|
||||
wakeup_softirqd();
|
||||
|
||||
account_softirq_exit(current);
|
||||
lockdep_softirq_end(in_hardirq);
|
||||
softirq_handle_end();
|
||||
|
||||
Reference in New Issue
Block a user