Skip to content

Commit 6b9ccbc

Browse files
yu-chen-surfPeter Zijlstra
authored andcommitted
kthread: Fix task state in kthread worker if being frozen
When analyzing a kernel waring message, Peter pointed out that there is a race condition when the kworker is being frozen and falls into try_to_freeze() with TASK_INTERRUPTIBLE, which could trigger a might_sleep() warning in try_to_freeze(). Although the root cause is not related to freeze()[1], it is still worthy to fix this issue ahead. One possible race scenario: CPU 0 CPU 1 ----- ----- // kthread_worker_fn set_current_state(TASK_INTERRUPTIBLE); suspend_freeze_processes() freeze_processes static_branch_inc(&freezer_active); freeze_kernel_threads pm_nosig_freezing = true; if (work) { //false __set_current_state(TASK_RUNNING); } else if (!freezing(current)) //false, been frozen freezing(): if (static_branch_unlikely(&freezer_active)) if (pm_nosig_freezing) return true; schedule() } // state is still TASK_INTERRUPTIBLE try_to_freeze() might_sleep() <--- warning Fix this by explicitly set the TASK_RUNNING before entering try_to_freeze(). Fixes: b56c0d8 ("kthread: implement kthread_worker") Suggested-by: Peter Zijlstra <[email protected]> Suggested-by: Andrew Morton <[email protected]> Signed-off-by: Chen Yu <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/lkml/Zs2ZoAcUsZMX2B%2FI@chenyu5-mobl2/ [1]
1 parent 84d2652 commit 6b9ccbc

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

kernel/kthread.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,16 @@ int kthread_worker_fn(void *worker_ptr)
845845
* event only cares about the address.
846846
*/
847847
trace_sched_kthread_work_execute_end(work, func);
848-
} else if (!freezing(current))
848+
} else if (!freezing(current)) {
849849
schedule();
850+
} else {
851+
/*
852+
* Handle the case where the current remains
853+
* TASK_INTERRUPTIBLE. try_to_freeze() expects
854+
* the current to be TASK_RUNNING.
855+
*/
856+
__set_current_state(TASK_RUNNING);
857+
}
850858

851859
try_to_freeze();
852860
cond_resched();

0 commit comments

Comments
 (0)