|
@@ -15,6 +15,7 @@
|
|
|
#include <linux/lockdep.h>
|
|
|
#include <linux/export.h>
|
|
|
#include <linux/sysctl.h>
|
|
|
+#include <linux/suspend.h>
|
|
|
#include <linux/utsname.h>
|
|
|
#include <linux/sched/signal.h>
|
|
|
#include <linux/sched/debug.h>
|
|
@@ -242,6 +243,28 @@ void reset_hung_task_detector(void)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(reset_hung_task_detector);
|
|
|
|
|
|
+static bool hung_detector_suspended;
|
|
|
+
|
|
|
+static int hungtask_pm_notify(struct notifier_block *self,
|
|
|
+ unsigned long action, void *hcpu)
|
|
|
+{
|
|
|
+ switch (action) {
|
|
|
+ case PM_SUSPEND_PREPARE:
|
|
|
+ case PM_HIBERNATION_PREPARE:
|
|
|
+ case PM_RESTORE_PREPARE:
|
|
|
+ hung_detector_suspended = true;
|
|
|
+ break;
|
|
|
+ case PM_POST_SUSPEND:
|
|
|
+ case PM_POST_HIBERNATION:
|
|
|
+ case PM_POST_RESTORE:
|
|
|
+ hung_detector_suspended = false;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return NOTIFY_OK;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* kthread which checks for tasks stuck in D state
|
|
|
*/
|
|
@@ -261,7 +284,8 @@ static int watchdog(void *dummy)
|
|
|
interval = min_t(unsigned long, interval, timeout);
|
|
|
t = hung_timeout_jiffies(hung_last_checked, interval);
|
|
|
if (t <= 0) {
|
|
|
- if (!atomic_xchg(&reset_hung_task, 0))
|
|
|
+ if (!atomic_xchg(&reset_hung_task, 0) &&
|
|
|
+ !hung_detector_suspended)
|
|
|
check_hung_uninterruptible_tasks(timeout);
|
|
|
hung_last_checked = jiffies;
|
|
|
continue;
|
|
@@ -275,6 +299,10 @@ static int watchdog(void *dummy)
|
|
|
static int __init hung_task_init(void)
|
|
|
{
|
|
|
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
|
|
|
+
|
|
|
+ /* Disable hung task detector on suspend */
|
|
|
+ pm_notifier(hungtask_pm_notify, 0);
|
|
|
+
|
|
|
watchdog_task = kthread_run(watchdog, NULL, "khungtaskd");
|
|
|
|
|
|
return 0;
|