diff options
| -rw-r--r-- | kernel/hung_task.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/kernel/hung_task.c b/kernel/hung_task.c index e0f90c2b57aa..d234022805dc 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c | |||
| @@ -185,10 +185,12 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) | |||
| 185 | rcu_read_unlock(); | 185 | rcu_read_unlock(); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static unsigned long timeout_jiffies(unsigned long timeout) | 188 | static long hung_timeout_jiffies(unsigned long last_checked, |
| 189 | unsigned long timeout) | ||
| 189 | { | 190 | { |
| 190 | /* timeout of 0 will disable the watchdog */ | 191 | /* timeout of 0 will disable the watchdog */ |
| 191 | return timeout ? timeout * HZ : MAX_SCHEDULE_TIMEOUT; | 192 | return timeout ? last_checked - jiffies + timeout * HZ : |
| 193 | MAX_SCHEDULE_TIMEOUT; | ||
| 192 | } | 194 | } |
| 193 | 195 | ||
| 194 | /* | 196 | /* |
| @@ -224,18 +226,21 @@ EXPORT_SYMBOL_GPL(reset_hung_task_detector); | |||
| 224 | */ | 226 | */ |
| 225 | static int watchdog(void *dummy) | 227 | static int watchdog(void *dummy) |
| 226 | { | 228 | { |
| 229 | unsigned long hung_last_checked = jiffies; | ||
| 230 | |||
| 227 | set_user_nice(current, 0); | 231 | set_user_nice(current, 0); |
| 228 | 232 | ||
| 229 | for ( ; ; ) { | 233 | for ( ; ; ) { |
| 230 | unsigned long timeout = sysctl_hung_task_timeout_secs; | 234 | unsigned long timeout = sysctl_hung_task_timeout_secs; |
| 235 | long t = hung_timeout_jiffies(hung_last_checked, timeout); | ||
| 231 | 236 | ||
| 232 | while (schedule_timeout_interruptible(timeout_jiffies(timeout))) | 237 | if (t <= 0) { |
| 233 | timeout = sysctl_hung_task_timeout_secs; | 238 | if (!atomic_xchg(&reset_hung_task, 0)) |
| 234 | 239 | check_hung_uninterruptible_tasks(timeout); | |
| 235 | if (atomic_xchg(&reset_hung_task, 0)) | 240 | hung_last_checked = jiffies; |
| 236 | continue; | 241 | continue; |
| 237 | 242 | } | |
| 238 | check_hung_uninterruptible_tasks(timeout); | 243 | schedule_timeout_interruptible(t); |
| 239 | } | 244 | } |
| 240 | 245 | ||
| 241 | return 0; | 246 | return 0; |
