[PATCH v2 2/3] kernel: set taint flag 'L' at any kind of lockup

From: Konstantin Khlebnikov
Date: Mon Jan 27 2020 - 09:03:51 EST


Any lockup or stall detector notifies about unexpected lack of progress.
It's better to know about these splats at investigating further problems.

This patch set TAINT_LOCKUP at:
- softlockup (CONFIG_SOFTLOCKUP_DETECTOR)
- hardlockup (CONFIG_HARDLOCKUP_DETECTOR)
- RCU stall (Documentation/RCU/stallwarn.txt)
- hung task (CONFIG_DETECT_HUNG_TASK)
- stuck in workqueues (CONFIG_WQ_WATCHDOG)

Signed-off-by: Konstantin Khlebnikov <khlebnikov@xxxxxxxxxxxxxx>
Acked-by: Paul E. McKenney <paulmck@xxxxxxxxxx> (RCU part)
Link: https://lore.kernel.org/lkml/157503370645.8187.6335564487789994134.stgit@buzz/ (v1)
---
Documentation/admin-guide/tainted-kernels.rst | 4 ++++
kernel/hung_task.c | 2 ++
kernel/rcu/tree_stall.h | 1 +
kernel/watchdog_hld.c | 1 +
kernel/workqueue.c | 1 +
5 files changed, 9 insertions(+)

diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
index 55d45211cb41..13249240283c 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -153,6 +153,10 @@ More detailed explanation for tainting
module signature.

14) ``L`` if a lockup has previously occurred on the system.
+ - soft/hardlockup, see Documentation/admin-guide/lockup-watchdogs.rst
+ - RCU stall, see Documentation/RCU/stallwarn.txt
+ - hung task detected, see CONFIG_DETECT_HUNG_TASK
+ - kernel workqueue lockup, see CONFIG_WQ_WATCHDOG

15) ``K`` if the kernel has been live patched.

diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index 14a625c16cb3..521eb2fbf5fc 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -139,6 +139,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
hung_task_show_lock = true;
}

+ add_taint(TAINT_LOCKUP, LOCKDEP_STILL_OK);
+
touch_nmi_watchdog();
}

diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h
index c0b8c458d8a6..181495efff80 100644
--- a/kernel/rcu/tree_stall.h
+++ b/kernel/rcu/tree_stall.h
@@ -74,6 +74,7 @@ early_initcall(check_cpu_stall_init);
/* If so specified via sysctl, panic, yielding cleaner stall-warning output. */
static void panic_on_rcu_stall(void)
{
+ add_taint(TAINT_LOCKUP, LOCKDEP_STILL_OK);
if (sysctl_panic_on_rcu_stall)
panic("RCU Stall\n");
}
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
index 247bf0b1582c..f77256f47422 100644
--- a/kernel/watchdog_hld.c
+++ b/kernel/watchdog_hld.c
@@ -152,6 +152,7 @@ static void watchdog_overflow_callback(struct perf_event *event,
!test_and_set_bit(0, &hardlockup_allcpu_dumped))
trigger_allbutself_cpu_backtrace();

+ add_taint(TAINT_LOCKUP, LOCKDEP_STILL_OK);
if (hardlockup_panic)
nmi_panic(regs, "Hard LOCKUP");

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index cfc923558e04..1b3c81d87a0d 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -5774,6 +5774,7 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
pr_cont_pool_info(pool);
pr_cont(" stuck for %us!\n",
jiffies_to_msecs(jiffies - pool_ts) / 1000);
+ add_taint(TAINT_LOCKUP, LOCKDEP_STILL_OK);
}
}