Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752440AbdGDQHc (ORCPT ); Tue, 4 Jul 2017 12:07:32 -0400 Received: from merlin.infradead.org ([205.233.59.134]:54142 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751960AbdGDQHa (ORCPT ); Tue, 4 Jul 2017 12:07:30 -0400 Date: Tue, 4 Jul 2017 18:07:21 +0200 From: Peter Zijlstra To: Vikram Mulukutla Cc: rusty@rustcorp.com.au, tj@kernel.org, Thomas Gleixner , akpm@linux-foundation.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: Re: [PATCH] kthread: Atomically set completion and perform dequeue in __kthread_parkme Message-ID: <20170704160721.oawhbx3efaw4d4we@hirez.programming.kicks-ass.net> References: <1498515483-12743-1-git-send-email-markivx@codeaurora.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1498515483-12743-1-git-send-email-markivx@codeaurora.org> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1244 Lines: 33 On Mon, Jun 26, 2017 at 03:18:03PM -0700, Vikram Mulukutla wrote: > kernel/kthread.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/kernel/kthread.c b/kernel/kthread.c > index 26db528..7ad3354 100644 > --- a/kernel/kthread.c > +++ b/kernel/kthread.c > @@ -171,9 +171,20 @@ static void __kthread_parkme(struct kthread *self) > { > __set_current_state(TASK_PARKED); > while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) { > + /* > + * Why the preempt_disable? > + * Hotplug needs to ensure that 'self' is off of the runqueue > + * as well, before scheduling the stopper thread that will > + * migrate tasks off of the runqeue that 'self' was running on. > + * This avoids unnecessary migration work and also ensures that > + * kthread_unpark in the cpu_up path doesn't race with > + * __kthread_parkme. > + */ > + preempt_disable(); > if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags)) > complete(&self->parked); > + schedule_preempt_disabled(); This is broken. schedule_preempt_disable() doesn't guarantee no preemptions, just makes it less likely. > + preempt_enable(); > __set_current_state(TASK_PARKED); > } > clear_bit(KTHREAD_IS_PARKED, &self->flags);