diff options
author | Vitaly Kuznetsov <vkuznets@redhat.com> | 2018-10-17 07:23:55 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-10-25 12:45:08 -0400 |
commit | a1c6ca3c6de763459a6e93b644ec6518c890ba1c (patch) | |
tree | 8583841917c0b636ea25a621946126cb0228b279 | |
parent | bd6bf7c10484f026505814b690104cdef27ed460 (diff) |
kernel: hung_task.c: disable on suspend
It is possible to observe hung_task complaints when system goes to
suspend-to-idle state:
# echo freeze > /sys/power/state
PM: Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.001 seconds) done.
OOM killer disabled.
Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
sd 0:0:0:0: [sda] Synchronizing SCSI cache
INFO: task bash:1569 blocked for more than 120 seconds.
Not tainted 4.19.0-rc3_+ #687
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
bash D 0 1569 604 0x00000000
Call Trace:
? __schedule+0x1fe/0x7e0
schedule+0x28/0x80
suspend_devices_and_enter+0x4ac/0x750
pm_suspend+0x2c0/0x310
Register a PM notifier to disable the detector on suspend and re-enable
back on wakeup.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | kernel/hung_task.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/kernel/hung_task.c b/kernel/hung_task.c index b9132d1269ef..cb8e3e8ac7b9 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/lockdep.h> | 15 | #include <linux/lockdep.h> |
16 | #include <linux/export.h> | 16 | #include <linux/export.h> |
17 | #include <linux/sysctl.h> | 17 | #include <linux/sysctl.h> |
18 | #include <linux/suspend.h> | ||
18 | #include <linux/utsname.h> | 19 | #include <linux/utsname.h> |
19 | #include <linux/sched/signal.h> | 20 | #include <linux/sched/signal.h> |
20 | #include <linux/sched/debug.h> | 21 | #include <linux/sched/debug.h> |
@@ -242,6 +243,28 @@ void reset_hung_task_detector(void) | |||
242 | } | 243 | } |
243 | EXPORT_SYMBOL_GPL(reset_hung_task_detector); | 244 | EXPORT_SYMBOL_GPL(reset_hung_task_detector); |
244 | 245 | ||
246 | static bool hung_detector_suspended; | ||
247 | |||
248 | static int hungtask_pm_notify(struct notifier_block *self, | ||
249 | unsigned long action, void *hcpu) | ||
250 | { | ||
251 | switch (action) { | ||
252 | case PM_SUSPEND_PREPARE: | ||
253 | case PM_HIBERNATION_PREPARE: | ||
254 | case PM_RESTORE_PREPARE: | ||
255 | hung_detector_suspended = true; | ||
256 | break; | ||
257 | case PM_POST_SUSPEND: | ||
258 | case PM_POST_HIBERNATION: | ||
259 | case PM_POST_RESTORE: | ||
260 | hung_detector_suspended = false; | ||
261 | break; | ||
262 | default: | ||
263 | break; | ||
264 | } | ||
265 | return NOTIFY_OK; | ||
266 | } | ||
267 | |||
245 | /* | 268 | /* |
246 | * kthread which checks for tasks stuck in D state | 269 | * kthread which checks for tasks stuck in D state |
247 | */ | 270 | */ |
@@ -261,7 +284,8 @@ static int watchdog(void *dummy) | |||
261 | interval = min_t(unsigned long, interval, timeout); | 284 | interval = min_t(unsigned long, interval, timeout); |
262 | t = hung_timeout_jiffies(hung_last_checked, interval); | 285 | t = hung_timeout_jiffies(hung_last_checked, interval); |
263 | if (t <= 0) { | 286 | if (t <= 0) { |
264 | if (!atomic_xchg(&reset_hung_task, 0)) | 287 | if (!atomic_xchg(&reset_hung_task, 0) && |
288 | !hung_detector_suspended) | ||
265 | check_hung_uninterruptible_tasks(timeout); | 289 | check_hung_uninterruptible_tasks(timeout); |
266 | hung_last_checked = jiffies; | 290 | hung_last_checked = jiffies; |
267 | continue; | 291 | continue; |
@@ -275,6 +299,10 @@ static int watchdog(void *dummy) | |||
275 | static int __init hung_task_init(void) | 299 | static int __init hung_task_init(void) |
276 | { | 300 | { |
277 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 301 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
302 | |||
303 | /* Disable hung task detector on suspend */ | ||
304 | pm_notifier(hungtask_pm_notify, 0); | ||
305 | |||
278 | watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); | 306 | watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); |
279 | 307 | ||
280 | return 0; | 308 | return 0; |