forked from Minki/linux
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 <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:85f1abe001
("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>
This commit is contained in:
parent
bf5015a50f
commit
b1f5b378e1
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user