From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0FAE3B9933 for ; Wed, 27 May 2026 08:29:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779870575; cv=none; b=M6PO3qpUIun1LGGS0jDRpeiViAPWYjruPuYnr4bg25d6TT6y97Va6sHo7tMq8gBxUkQSiH9OFZhegPGmxOEcKsSM+OQyi/Is8umBaPy3Er/UqPOXmdZrevpc8qocI5XZGMOY6tl4dnJgYu2/C64lOoIr5/1lyxMYtXFrYUOvOhE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779870575; c=relaxed/simple; bh=vRHe6HAvDKnWPU0d4i5hr8Vf0qFQcFo3+ukauhRofY0=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=mh93qGyyhTzJgy5J2YLMpXzoNO7f0KXb3T4tkv1jdQfSMwPuCnC9t9Q6AniUtIZMJ6mpiMrEIOru/2K1i1+FnCzlBl9tjVLy7Kt5r/XZpwF/cYA/NbSeiWi9xOHrNNSmL4RptGLkYVJ3rpfiJ0NzkRi5y/+gpQcc4mLGOQX8/D0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=M0BvVdC7; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="M0BvVdC7" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=In-Reply-To:Content-Transfer-Encoding: Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date: Sender:Reply-To:Content-ID:Content-Description; bh=X3QPSXezPoIzEUzNpD/oWLTpaoQxbuYiaPXo0N5y9SE=; b=M0BvVdC71g2xj205gWK+6kZsA+ UN+W5UzcbxSShUJ8GeJ79XVzrr3ONEcCo9h/czknalPqwDs7+/ByC0fhu2URcolUqgRGcBZVcKhJJ e7T1irWGPdMzTRJw8nsAMTHWAgAK8sIjgyp0cIo+C3qp07dWAQ8J9cMN3icP5FYPDyFZWOcfSxibG ar5QczGc3W47oeXGfPnjHI2tl4OzqJOzY4acC7ESzcTIAqIYGsMyQPoWfeZu36ezXYmHoIG0/3WBk dOEG2HqZn2ARhyBdIx30j0BpCMROJKNz9DDGcIYv5Tm/e7Nfr/b9dnCQirHDNaqhAMB67qDQSB+MS YVRulcvg==; Received: from 2001-1c00-8d85-4b00-266e-96ff-fe07-7dcc.cable.dynamic.v6.ziggo.nl ([2001:1c00:8d85:4b00:266e:96ff:fe07:7dcc] helo=noisy.programming.kicks-ass.net) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wS9de-0000000272m-2r90; Wed, 27 May 2026 08:29:18 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 1000) id DEDEE300673; Wed, 27 May 2026 10:29:16 +0200 (CEST) Date: Wed, 27 May 2026 10:29:16 +0200 From: Peter Zijlstra To: John Stultz Cc: K Prateek Nayak , Joel Fernandes , Qais Yousef , Ingo Molnar , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Valentin Schneider , Steven Rostedt , Ben Segall , Zimuzo Ezeozue , Will Deacon , Waiman Long , Boqun Feng , "Paul E. McKenney" , Metin Kaya , Xuewen Yan , Thomas Gleixner , Daniel Lezcano , Suleiman Souhlal , kuyo chang , hupu , linux-kernel@vger.kernel.org, Mike Galbraith Subject: Re: [PATCH 4/6] sched/proxy: Switch proxy to use p->is_blocked Message-ID: <20260527082916.GP3126523@noisy.programming.kicks-ass.net> References: <20260526111609.433880331@infradead.org> <20260526113322.477954312@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: On Tue, May 26, 2026 at 07:25:13PM -0700, John Stultz wrote: > On Tue, May 26, 2026 at 4:16 AM Peter Zijlstra wrote: > > > > Rather than gate the proxy paths with p->blocked_on, use p->is_blocked. > > > > This opens up the state: '->is_blocked && !->blocked_on' for future use. > > > > Notably, only proxy and delayed tasks can be ->on_rq && ->is_blocked, and it is > > guaranteed that sched_class::pick_task() will never return a delayed task. > > Therefore any task returned from pick_next_task() that has ->is_blocked set, > > must be a proxy task. > > While this seems true, it also feels very subtle. > > Just taking a step back, while it might be possible, I'm not sure I'm > totally seeing the benefit of doing this. > > When we were playing around with the idea of keeping ptr+latch-bit in > the blocked_on field, using NULL+latch to replace PROXY_WAKING made > sense, but with is_blocked being used for more than just proxy logic, > I'm not sure encoding meaning across the two fields is particularly > intuitive (and def seems more error prone). Is the special > PROXY_WAKING value really so awful? Or maybe does it make sense to > have different values for is_blocked (DELAYED, PROXY) so we can better > separate the variants when combining with blocked_on? > > It is a little funny to see how close this is getting to the separate > blocked_on_state + blocked_on management I had way back when before we > compressed that down with PROXY_WAKING. :) Yeah, I was thinking the same. But then last night, after it cooled down a bit, my brain started working again and I realized that there is a simple test that should work. Basically, *IF* we are proxy migrated -- and thus need a return migration -- then task_cpu(p) != p->wake_cpu, per proxy_set_task_cpu(). This doesn't suffer the random migration issues you get from purely checking against p->cpus_ptr, and it is more specific than PROXY_WAKING, in that it will really only do the long path / migration if we do in fact need return migration. If we stayed on the right CPU, we simply stay there. So I've stuck the below into the series between 3 and 4. This seems to survive boot with ww_mutex selftest and hackbench. --- kernel/sched/core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3767,6 +3767,21 @@ static inline bool proxy_needs_return(st if (!task_is_blocked(p)) return false; + /* + * Typically per __set_task_cpu(), task_cpu(p) == p->wake_cpu. + * + * However, proxy_set_task_cpu() is such that it preserves the + * original cpu in p->wake_cpu while migrating p for proxy reasons + * (possibly outside of the allowed p->cpus_ptr). + * + * Furthermore, migration_cpu_stop() / __migrate_swap_task(), will + * only set p->wake_cpu when !p->on_rq, and since here p->on_rq, this + * will not apply. But if it did, this check is the safe way around + * and would migrate. + */ + if (task_cpu(p) == p->wake_cpu) + return false; + scoped_guard(raw_spinlock, &p->blocked_lock) { /* Task is waking up; clear any blocked_on relationship */ __clear_task_blocked_on(p, NULL);