[lkml]   [2018]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH 3.18 23/85] kthread, sched/wait: Fix kthread_parkme() wait-loop
3.18-stable review patch.  If anyone has any objections, please let me know.


From: Peter Zijlstra <>

[ Upstream commit 741a76b350897604c48fb12beff1c9b77724dc96 ]

Gaurav reported a problem with __kthread_parkme() where a concurrent
try_to_wake_up() could result in competing stores to ->state which,
when the TASK_PARKED store got lost bad things would happen.

The comment near set_current_state() actually mentions this competing
store, but only mentions the case against TASK_RUNNING. This same
store, with different timing, can happen against a subsequent !RUNNING

This normally is not a problem, because as per that same comment, the
!RUNNING state store is inside a condition based wait-loop:

for (;;) {
if (!need_sleep)

If we loose the (first) TASK_UNINTERRUPTIBLE store to a previous
(concurrent) wakeup, the schedule() will NO-OP and we'll go around the
loop once more.

The problem here is that the TASK_PARKED store is not inside the
KTHREAD_SHOULD_PARK condition wait-loop.

There is a genuine issue with sleeps that do not have a condition;
this is addressed in a subsequent patch.

Reported-by: Gaurav Kohli <>
Signed-off-by: Peter Zijlstra (Intel) <>
Reviewed-by: Oleg Nesterov <>
Cc: Linus Torvalds <>
Cc: Peter Zijlstra <>
Cc: Thomas Gleixner <>
Signed-off-by: Ingo Molnar <>
Signed-off-by: Sasha Levin <>
Signed-off-by: Greg Kroah-Hartman <>
kernel/kthread.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -156,12 +156,13 @@ void *probe_kthread_data(struct task_str

static void __kthread_parkme(struct kthread *self)
- __set_current_state(TASK_PARKED);
- while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) {
+ for (;;) {
+ set_current_state(TASK_PARKED);
+ if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
+ break;
if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags))
- __set_current_state(TASK_PARKED);
clear_bit(KTHREAD_IS_PARKED, &self->flags);

 \ /
  Last update: 2018-07-01 20:43    [W:0.363 / U:1.288 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site