116 lines
3.6 KiB
Diff
116 lines
3.6 KiB
Diff
From f148f4152b11a7592f60ca3e679b0c4a2a40c926 Mon Sep 17 00:00:00 2001
|
|
Message-Id: <f148f4152b11a7592f60ca3e679b0c4a2a40c926.1594742966.git.zanussi@kernel.org>
|
|
In-Reply-To: <832f7d97d6b989a5b4860dd2dbec58ad6ad5ab81.1594742966.git.zanussi@kernel.org>
|
|
References: <832f7d97d6b989a5b4860dd2dbec58ad6ad5ab81.1594742966.git.zanussi@kernel.org>
|
|
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
Date: Mon, 18 Feb 2019 13:19:59 +0100
|
|
Subject: [PATCH 125/329] softirq: Avoid "local_softirq_pending" messages if
|
|
ksoftirqd is blocked
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.132-rt59.tar.xz
|
|
|
|
If the ksoftirqd thread has a softirq pending and is blocked on the
|
|
`local_softirq_locks' lock then softirq_check_pending_idle() won't
|
|
complain because the "lock owner" will mask away this softirq from the
|
|
mask of pending softirqs.
|
|
If ksoftirqd has an additional softirq pending then it won't be masked
|
|
out because we never look at ksoftirqd's mask.
|
|
|
|
If there are still pending softirqs while going to idle check
|
|
ksoftirqd's and ktimersfotd's mask before complaining about unhandled
|
|
softirqs.
|
|
|
|
Cc: stable-rt@vger.kernel.org
|
|
Tested-by: Juri Lelli <juri.lelli@redhat.com>
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
---
|
|
kernel/softirq.c | 57 ++++++++++++++++++++++++++++++++++--------------
|
|
1 file changed, 41 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/kernel/softirq.c b/kernel/softirq.c
|
|
index fe4e59c80a08..1920985eeb09 100644
|
|
--- a/kernel/softirq.c
|
|
+++ b/kernel/softirq.c
|
|
@@ -92,6 +92,31 @@ static inline void softirq_clr_runner(unsigned int sirq)
|
|
sr->runner[sirq] = NULL;
|
|
}
|
|
|
|
+static bool softirq_check_runner_tsk(struct task_struct *tsk,
|
|
+ unsigned int *pending)
|
|
+{
|
|
+ bool ret = false;
|
|
+
|
|
+ if (!tsk)
|
|
+ return ret;
|
|
+
|
|
+ /*
|
|
+ * The wakeup code in rtmutex.c wakes up the task
|
|
+ * _before_ it sets pi_blocked_on to NULL under
|
|
+ * tsk->pi_lock. So we need to check for both: state
|
|
+ * and pi_blocked_on.
|
|
+ */
|
|
+ raw_spin_lock(&tsk->pi_lock);
|
|
+ if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING) {
|
|
+ /* Clear all bits pending in that task */
|
|
+ *pending &= ~(tsk->softirqs_raised);
|
|
+ ret = true;
|
|
+ }
|
|
+ raw_spin_unlock(&tsk->pi_lock);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/*
|
|
* On preempt-rt a softirq running context might be blocked on a
|
|
* lock. There might be no other runnable task on this CPU because the
|
|
@@ -104,6 +129,7 @@ static inline void softirq_clr_runner(unsigned int sirq)
|
|
*/
|
|
void softirq_check_pending_idle(void)
|
|
{
|
|
+ struct task_struct *tsk;
|
|
static int rate_limit;
|
|
struct softirq_runner *sr = this_cpu_ptr(&softirq_runners);
|
|
u32 warnpending;
|
|
@@ -113,24 +139,23 @@ void softirq_check_pending_idle(void)
|
|
return;
|
|
|
|
warnpending = local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK;
|
|
+ if (!warnpending)
|
|
+ return;
|
|
for (i = 0; i < NR_SOFTIRQS; i++) {
|
|
- struct task_struct *tsk = sr->runner[i];
|
|
+ tsk = sr->runner[i];
|
|
|
|
- /*
|
|
- * The wakeup code in rtmutex.c wakes up the task
|
|
- * _before_ it sets pi_blocked_on to NULL under
|
|
- * tsk->pi_lock. So we need to check for both: state
|
|
- * and pi_blocked_on.
|
|
- */
|
|
- if (tsk) {
|
|
- raw_spin_lock(&tsk->pi_lock);
|
|
- if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING) {
|
|
- /* Clear all bits pending in that task */
|
|
- warnpending &= ~(tsk->softirqs_raised);
|
|
- warnpending &= ~(1 << i);
|
|
- }
|
|
- raw_spin_unlock(&tsk->pi_lock);
|
|
- }
|
|
+ if (softirq_check_runner_tsk(tsk, &warnpending))
|
|
+ warnpending &= ~(1 << i);
|
|
+ }
|
|
+
|
|
+ if (warnpending) {
|
|
+ tsk = __this_cpu_read(ksoftirqd);
|
|
+ softirq_check_runner_tsk(tsk, &warnpending);
|
|
+ }
|
|
+
|
|
+ if (warnpending) {
|
|
+ tsk = __this_cpu_read(ktimer_softirqd);
|
|
+ softirq_check_runner_tsk(tsk, &warnpending);
|
|
}
|
|
|
|
if (warnpending) {
|
|
--
|
|
2.17.1
|
|
|