aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kthread.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2018-05-04 05:11:42 -0400
committerIngo Molnar <mingo@kernel.org>2018-05-25 02:03:51 -0400
commitb1f5b378e126133521df668379249fb8265121f1 (patch)
treeee2ffdde3e7ca65a6090babe51ae1851411e0903 /kernel/kthread.c
parentbf5015a50f1fdb248b48405b67cae24dc02605d6 (diff)
kthread: Allow kthread_park() on a parked kthread
The following commit: 85f1abe0019f ("kthread, sched/wait: Fix kthread_parkme() completion issue") added a WARN() in the case where we call kthread_park() on an already parked thread, because the old code wasn't doing the right thing there and it wasn't at all clear that would happen. It turns out, this does in fact happen, so we have to deal with it. Instead of potentially returning early, also wait for the completion. This does however mean we have to use complete_all() and re-initialize the completion on re-use. Reported-by: LKP <lkp@01.org> Tested-by: Meelis Roos <mroos@linux.ee> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: kernel test robot <lkp@intel.com> Cc: wfg@linux.intel.com Cc: Thomas Gleixner <tglx@linutronix.de> Fixes: 85f1abe0019f ("kthread, sched/wait: Fix kthread_parkme() completion issue") Link: http://lkml.kernel.org/r/20180504091142.GI12235@hirez.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/kthread.c')
-rw-r--r--kernel/kthread.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 2017a39ab490..481951bf091d 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -193,7 +193,7 @@ EXPORT_SYMBOL_GPL(kthread_parkme);
193 193
194void kthread_park_complete(struct task_struct *k) 194void kthread_park_complete(struct task_struct *k)
195{ 195{
196 complete(&to_kthread(k)->parked); 196 complete_all(&to_kthread(k)->parked);
197} 197}
198 198
199static int kthread(void *_create) 199static int kthread(void *_create)
@@ -459,6 +459,7 @@ void kthread_unpark(struct task_struct *k)
459 if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) 459 if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags))
460 __kthread_bind(k, kthread->cpu, TASK_PARKED); 460 __kthread_bind(k, kthread->cpu, TASK_PARKED);
461 461
462 reinit_completion(&kthread->parked);
462 clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); 463 clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
463 wake_up_state(k, TASK_PARKED); 464 wake_up_state(k, TASK_PARKED);
464} 465}
@@ -483,9 +484,6 @@ int kthread_park(struct task_struct *k)
483 if (WARN_ON(k->flags & PF_EXITING)) 484 if (WARN_ON(k->flags & PF_EXITING))
484 return -ENOSYS; 485 return -ENOSYS;
485 486
486 if (WARN_ON_ONCE(test_bit(KTHREAD_SHOULD_PARK, &kthread->flags)))
487 return -EBUSY;
488
489 set_bit(KTHREAD_SHOULD_PARK, &kthread->flags); 487 set_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
490 if (k != current) { 488 if (k != current) {
491 wake_up_process(k); 489 wake_up_process(k);