mirror of
https://github.com/torvalds/linux.git
synced 2026-10-07 22:37:45 -04:00
kthread: Allow kthread_park() on a parked kthread
The following commit:85f1abe001("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 <[email protected]> Tested-by: Meelis Roos <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: kernel test robot <[email protected]> Cc: [email protected] Cc: Thomas Gleixner <[email protected]> Fixes:85f1abe001("kthread, sched/wait: Fix kthread_parkme() completion issue") Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
1 parent
bf5015a50f
commit
b1f5b378e1
1 file changed
+2
-4
+2
-4
@@ -193,7 +193,7 @@ EXPORT_SYMBOL_GPL(kthread_parkme);
|
||||
|
||||
void kthread_park_complete(struct task_struct *k)
|
||||
{
|
||||
complete(&to_kthread(k)->parked);
|
||||
complete_all(&to_kthread(k)->parked);
|
||||
}
|
||||
|
||||
static int kthread(void *_create)
|
||||
@@ -459,6 +459,7 @@ void kthread_unpark(struct task_struct *k)
|
||||
if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags))
|
||||
__kthread_bind(k, kthread->cpu, TASK_PARKED);
|
||||
|
||||
reinit_completion(&kthread->parked);
|
||||
clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
|
||||
wake_up_state(k, TASK_PARKED);
|
||||
}
|
||||
@@ -483,9 +484,6 @@ int kthread_park(struct task_struct *k)
|
||||
if (WARN_ON(k->flags & PF_EXITING))
|
||||
return -ENOSYS;
|
||||
|
||||
if (WARN_ON_ONCE(test_bit(KTHREAD_SHOULD_PARK, &kthread->flags)))
|
||||
return -EBUSY;
|
||||
|
||||
set_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
|
||||
if (k != current) {
|
||||
wake_up_process(k);
|
||||
|
||||
Reference in new issue
Block a user