diff options
Diffstat (limited to 'kernel/hung_task.c')
| -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; |
