All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrea Righi <arighi@nvidia.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>,
	Ingo Molnar <mingo@redhat.com>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
	Valentin Schneider <vschneid@redhat.com>,
	Tejun Heo <tj@kernel.org>,
	Patrick Bellasi <patrick.bellasi@arm.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] sched: Skip class callbacks with SCHED_FLAG_KEEP_PARAMS
Date: Thu, 30 Jul 2026 13:42:56 +0200	[thread overview]
Message-ID: <ams4wCXPnmUOhtvP@gpd4> (raw)
In-Reply-To: <20260730095737.GO49951@noisy.programming.kicks-ass.net>

Hi Peter,

On Thu, Jul 30, 2026 at 11:57:37AM +0200, Peter Zijlstra wrote:
> On Thu, Jul 30, 2026 at 12:59:37PM +0530, K Prateek Nayak wrote:
> > Hello Andrea,
> > 
> > On 7/30/2026 11:20 AM, Andrea Righi wrote:
> > > SCHED_FLAG_KEEP_PARAMS suppresses scheduler parameter and class changes,
> > > but __sched_setscheduler() can still set DEQUEUE_CLASS when the class
> > > computed from the requested policy differs from the task's current
> > > class.
> > > 
> > > This causes the switching_from(), switched_from(), switching_to() and
> > > switched_to() callbacks to run even though p->sched_class remains
> > > unchanged.
> > > 
> > > Set DEQUEUE_CLASS only when the sched class is allowed to change.
> > > 
> > > Fixes: 637b0682821b ("sched: Fold sched_class::switch{ing,ed}_{to,from}() into the change pattern")
> > > Signed-off-by: Andrea Righi <arighi@nvidia.com>
> > > ---
> > >  kernel/sched/syscalls.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
> > > index b215b0ead9a60..903b47f5d0b74 100644
> > > --- a/kernel/sched/syscalls.c
> > > +++ b/kernel/sched/syscalls.c
> > > @@ -675,7 +675,8 @@ int __sched_setscheduler(struct task_struct *p,
> > >  	prev_class = p->sched_class;
> > >  	next_class = __setscheduler_class(policy, newprio);
> > >  
> > > -	if (prev_class != next_class)
> > > +	if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS) &&
> > > +	    prev_class != next_class)
> > >  		queue_flags |= DEQUEUE_CLASS;
> > 
> > It seems there also exists a SCHED_FLAG_KEEP_POLICY which should be used
> > to retain the policy. By a quick look at the syscall path,
> > SCHED_FLAG_KEEP_PARAMS should just do an equivalent of:
> > 
> >     get_params(p, &attr, 0)
> > 
> > and match the some properties of sched_attr with that of the task.
> > 
> > The task is still free to switch classes if the attr->sched_policy
> > differs given SCHED_FLAG_KEEP_PARAMS and SCHED_FLAG_KEEP_POLICY are two
> > distinct flags and there is a separate SCHED_FLAG_KEEP_ALL to combines
> > them both.
> > 
> > I'm having a sneaky suspicion that the bit in sched_change guard below
> > should actually check for SCHED_FLAG_KEEP_ALL like:
> > 
> > diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
> > index b215b0ead9a6..baf1fc59069e 100644
> > --- a/kernel/sched/syscalls.c
> > +++ b/kernel/sched/syscalls.c
> > @@ -680,7 +680,7 @@ int __sched_setscheduler(struct task_struct *p,
> >  
> >  	scoped_guard (sched_change, p, queue_flags) {
> >  
> > -		if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
> > +		if ((attr->sched_flags & SCHED_FLAG_KEEP_ALL) != SCHED_FLAG_KEEP_ALL) {
> >  			__setscheduler_params(p, attr);
> >  			p->sched_class = next_class;
> >  			p->prio = newprio;
> 
> Hmm, but if we have KEEP_PARAMS then params are loaded with the current
> set and actually re-setting them doesn't matter. So perhaps we should
> just remove that conditional entirely?
> 
> ---
> diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
> index b215b0ead9a6..1893938c76db 100644
> --- a/kernel/sched/syscalls.c
> +++ b/kernel/sched/syscalls.c
> @@ -680,12 +680,10 @@ int __sched_setscheduler(struct task_struct *p,
>  
>  	scoped_guard (sched_change, p, queue_flags) {
>  
> -		if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
> -			__setscheduler_params(p, attr);
> -			p->sched_class = next_class;
> -			p->prio = newprio;
> -			__setscheduler_dl_pi(newprio, policy, p, scope);
> -		}
> +		__setscheduler_params(p, attr);
> +		p->sched_class = next_class;
> +		p->prio = newprio;
> +		__setscheduler_dl_pi(newprio, policy, p, scope);
>  		__setscheduler_uclamp(p, attr);
>  
>  		if (scope->queued) {
> @@ -979,8 +977,11 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr,
>  	if (!p)
>  		return -ESRCH;
>  
> -	if (attr.sched_flags & SCHED_FLAG_KEEP_PARAMS)
> +	if (attr.sched_flags & SCHED_FLAG_KEEP_PARAMS) {
> +		if (attr.sched_policy != SETPARAM_POLICY && attr.sched_policy != p->policy)
> +			return -EINVAL;
>  		get_params(p, &attr, 0);
> +	}
>  
>  	return sched_setattr(p, &attr);
>  }

Rejecting a policy change when KEEP_PARAMS is set makes sense to me.

However, I don't think we can remove the conditional and reapply the values
returned by get_params(). That snapshot is taken before the rq lock is acquired,
so a concurrent scheduler update could change the parameters in between.

What about retaining the existing update conditional and rejecting KEEP_PARAMS
with policy != p->policy under the rq lock, after the existing policy recheck?

KEEP_POLICY will already have been resolved to the current policy there. This
should prevent both the spurious class callbacks and the deadline bandwidth
accounting issue at their source.

Thanks,
-Andrea

  reply	other threads:[~2026-07-30 11:43 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-30  5:50 [PATCH 0/2] sched: Fix SCHED_FLAG_KEEP_PARAMS side effects Andrea Righi
2026-07-30  5:50 ` [PATCH 1/2] sched: Skip class callbacks with SCHED_FLAG_KEEP_PARAMS Andrea Righi
2026-07-30  7:29   ` K Prateek Nayak
2026-07-30  8:57     ` Andrea Righi
2026-07-30  9:57     ` Peter Zijlstra
2026-07-30 11:42       ` Andrea Righi [this message]
2026-07-30  5:56 ` [PATCH 2/2] sched/deadline: Skip bandwidth accounting " Andrea Righi
2026-07-30 10:04   ` Peter Zijlstra
2026-07-30  9:32 ` [PATCH 0/2] sched: Fix SCHED_FLAG_KEEP_PARAMS side effects Peter Zijlstra
2026-07-30  9:52   ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ams4wCXPnmUOhtvP@gpd4 \
    --to=arighi@nvidia.com \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=juri.lelli@redhat.com \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=patrick.bellasi@arm.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tj@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.