diff options
| author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2008-02-08 09:41:13 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-02-29 12:46:53 -0500 |
| commit | 7be2a03e3174cee3a3cdcdf17db357470f51caff (patch) | |
| tree | fcc341251c8fcab1b950d7bda25de9ca09fc5363 /kernel | |
| parent | 2232c2d8e0a6a31061dec311f3d1cf7624bc14f1 (diff) | |
softlockup: fix task state setting
kthread_stop() can be called when a 'watchdog' thread is executing after
kthread_should_stop() but before set_task_state(TASK_INTERRUPTIBLE).
Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/softlockup.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 7c2da88db4ed..01b6522fd92b 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
| @@ -216,26 +216,27 @@ static int watchdog(void *__bind_cpu) | |||
| 216 | /* initialize timestamp */ | 216 | /* initialize timestamp */ |
| 217 | touch_softlockup_watchdog(); | 217 | touch_softlockup_watchdog(); |
| 218 | 218 | ||
| 219 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 219 | /* | 220 | /* |
| 220 | * Run briefly once per second to reset the softlockup timestamp. | 221 | * Run briefly once per second to reset the softlockup timestamp. |
| 221 | * If this gets delayed for more than 60 seconds then the | 222 | * If this gets delayed for more than 60 seconds then the |
| 222 | * debug-printout triggers in softlockup_tick(). | 223 | * debug-printout triggers in softlockup_tick(). |
| 223 | */ | 224 | */ |
| 224 | while (!kthread_should_stop()) { | 225 | while (!kthread_should_stop()) { |
| 225 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 226 | touch_softlockup_watchdog(); | 226 | touch_softlockup_watchdog(); |
| 227 | schedule(); | 227 | schedule(); |
| 228 | 228 | ||
| 229 | if (kthread_should_stop()) | 229 | if (kthread_should_stop()) |
| 230 | break; | 230 | break; |
| 231 | 231 | ||
| 232 | if (this_cpu != check_cpu) | 232 | if (this_cpu == check_cpu) { |
| 233 | continue; | 233 | if (sysctl_hung_task_timeout_secs) |
| 234 | 234 | check_hung_uninterruptible_tasks(this_cpu); | |
| 235 | if (sysctl_hung_task_timeout_secs) | 235 | } |
| 236 | check_hung_uninterruptible_tasks(this_cpu); | ||
| 237 | 236 | ||
| 237 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 238 | } | 238 | } |
| 239 | __set_current_state(TASK_RUNNING); | ||
| 239 | 240 | ||
| 240 | return 0; | 241 | return 0; |
| 241 | } | 242 | } |
