lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aHel4LvT_Y5gpYfy@gpd4>
Date: Wed, 16 Jul 2025 15:15:12 +0200
From: Andrea Righi <arighi@...dia.com>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Breno Leitao <leitao@...ian.org>, Tejun Heo <tj@...nel.org>,
	David Vernet <void@...ifault.com>,
	Changwoo Min <changwoo@...lia.com>, Ingo Molnar <mingo@...hat.com>,
	Juri Lelli <juri.lelli@...hat.com>,
	Vincent Guittot <vincent.guittot@...aro.org>,
	Dietmar Eggemann <dietmar.eggemann@....com>,
	Steven Rostedt <rostedt@...dmis.org>,
	Ben Segall <bsegall@...gle.com>, Mel Gorman <mgorman@...e.de>,
	Valentin Schneider <vschneid@...hat.com>, sched-ext@...ts.linux.dev,
	linux-kernel@...r.kernel.org, kernel-team@...a.com,
	jake@...lion.co.uk
Subject: Re: [PATCH] sched/ext: Suppress warning in __this_cpu_write() by
 disabling preemption

On Wed, Jul 16, 2025 at 02:51:28PM +0200, Peter Zijlstra wrote:
> On Wed, Jul 16, 2025 at 05:46:15AM -0700, Breno Leitao wrote:
> > __this_cpu_write() emits a warning if used with preemption enabled.
> > 
> > Function update_locked_rq() might be called with preemption enabled,
> > which causes the following warning:
> > 
> > 	BUG: using __this_cpu_write() in preemptible [00000000] code: scx_layered_6-9/68770
> > 
> > Disable preemption around the __this_cpu_write() call in
> > update_locked_rq() to suppress the warning, without affecting behavior.
> > 
> > If preemption triggers a  jump to another CPU during the callback it's
> > fine, since we would track the rq state on the other CPU with its own
> > local variable.
> > 
> > Suggested-by: Andrea Righi <arighi@...dia.com>
> > Signed-off-by: Breno Leitao <leitao@...ian.org>
> > Fixes: 18853ba782bef ("sched_ext: Track currently locked rq")
> > Acked-by: Andrea Righi <arighi@...dia.com>
> > ---
> >  kernel/sched/ext.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
> > index b498d867ba210..24fcbd7331f73 100644
> > --- a/kernel/sched/ext.c
> > +++ b/kernel/sched/ext.c
> > @@ -1258,7 +1258,14 @@ static inline void update_locked_rq(struct rq *rq)
> >  	 */
> >  	if (rq)
> >  		lockdep_assert_rq_held(rq);
> > +	/*
> > +	 * __this_cpu_write() emits a warning when used with preemption enabled.
> > +	 * While there's no functional issue if the callback runs on another
> > +	 * CPU, we disable preemption here solely to suppress that warning.
> > +	 */
> > +	preempt_disable();
> >  	__this_cpu_write(locked_rq, rq);
> > +	preempt_enable();
> >  }
> 
> This looks dodgy as heck. Why can't we do this update_locked_rq(NULL)
> call while still holding rq? Also, I don't seem to have this scx_layered
> thing.

Giving more context.

The idea is to track the scx callbacks that are invoked with a rq lock held
and, in those cases, store the locked rq. However, some callbacks may also
be invoked from an unlocked context, where no rq is locked and in this case
rq should be NULL.

In the latter case, it's acceptable for preemption to remain enabled, but
we still want to explicitly set locked_rq = NULL. If during the execution
of the callback we jump on another CPU, it'd still be in an unlocked state,
so it's locked_rq is still NULL.

Basically we would need preempt_disable/enable() only when rq == NULL to be
formally correct. And if rq != NULL we should probably trigger a warning,
as initially suggested by Breno.

How about something like this?

static inline void update_locked_rq(struct rq *rq)
{
	if (rq) {
		lockdep_assert_rq_held(rq);
		WARN_ON_ONCE(preemptible());
		__this_cpu_write(locked_rq, rq);
		return;
	}

	/*
	 * Certain callbacks may be invoked from an unlocked context, where
	 * no rq is held. In those cases, we still want to constently set
	 * locked_rq to NULL, disabling preemption.
	 */
	preempt_disable();
	__this_cpu_write(locked_rq, NULL);
	preempt_enable();
}

Thanks,
-Andrea

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ