summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:02:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:02:38 +0000
commit08b74a000942a380fe028845f92cd3a0dee827d5 (patch)
treeaa78b4e12607c3e1fcce8d5cc42df4330792f118 /debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch
parentAdding upstream version 4.19.249. (diff)
downloadlinux-08b74a000942a380fe028845f92cd3a0dee827d5.tar.xz
linux-08b74a000942a380fe028845f92cd3a0dee827d5.zip
Adding debian version 4.19.249-2.debian/4.19.249-2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch')
-rw-r--r--debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch112
1 files changed, 112 insertions, 0 deletions
diff --git a/debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch b/debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch
new file mode 100644
index 000000000..1302bc0ef
--- /dev/null
+++ b/debian/patches-rt/0125-softirq-Avoid-local_softirq_pending-messages-if-ksof.patch
@@ -0,0 +1,112 @@
+From 287a0b153109b1e2d548befe904bc14f3de5f2c8 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Mon, 18 Feb 2019 13:19:59 +0100
+Subject: [PATCH 125/347] 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.246-rt110.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.36.1
+