Re: [PATCH 04/14] sched: Add prepare_switch() class callback

[email protected] Sat, 25 Jul 2026 16:25:23 +0000
Newsgroups dev.linux.lists.sched-ext
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(=
s) to consider:
- [Medium] The `prepare_switch()` callback is invoked on the incoming `next=
_class`, but the task may never actually transition to that class if `SCHED=
_FLAG_KEEP_PARAMS` is set, leaving the prepared state orphaned and leaking =
resources.
--

--- Patch [4]: [PATCH 04/14] sched: Add prepare_switch() class callback ---
commit f8056ba7bb47e84cdf2c8a5193c3485b3b2d44d0
Author: Andrea Righi <[email protected]>

sched: Add prepare_switch() class callback

This commit introduces a prepare_switch() callback for scheduling classes.
It allows an incoming class to prepare a task while the state is still
live, before the normal dequeue and class transition take place.

> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 37c87783439f5..66e9ba50f5639 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
[ ... ]
> @@ -11221,7 +11221,9 @@ static inline void sched_mm_cid_fork(struct task_=
struct *t) { }
> =20
>  static DEFINE_PER_CPU(struct sched_change_ctx, sched_change_ctx);
> =20
> -struct sched_change_ctx *sched_change_begin(struct task_struct *p, unsig=
ned int flags)
> +struct sched_change_ctx *
> +sched_change_begin(struct task_struct *p, const struct sched_class *next=
_class,
> +		   unsigned int flags)
>  {
>  	struct sched_change_ctx *ctx =3D this_cpu_ptr(&sched_change_ctx);
>  	struct rq *rq =3D task_rq(p);
> @@ -11239,6 +11241,10 @@ struct sched_change_ctx *sched_change_begin(stru=
ct task_struct *p, unsigned int
>  		flags |=3D DEQUEUE_NOCLOCK;
>  	}
> =20
> +	if ((flags & DEQUEUE_CLASS) && next_class !=3D p->sched_class &&
> +	    next_class->prepare_switch)
> +		next_class->prepare_switch(rq, p);
> +
>  	if ((flags & DEQUEUE_CLASS) && p->sched_class->switching_from)
>  		p->sched_class->switching_from(rq, p);
> =20
[ ... ]
> diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
> index b215b0ead9a60..bc32ce76ff4fe 100644
> --- a/kernel/sched/syscalls.c
> +++ b/kernel/sched/syscalls.c
[ ... ]
> @@ -678,7 +678,7 @@ int __sched_setscheduler(struct task_struct *p,
>  	if (prev_class !=3D next_class)
>  		queue_flags |=3D DEQUEUE_CLASS;
> =20
> -	scoped_guard (sched_change, p, queue_flags) {
> +	scoped_guard (sched_change, p, next_class, queue_flags) {
> =20
>  		if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
>  			__setscheduler_params(p, attr);

[Severity: Medium]
Will this leak resources if a user calls sched_setattr() with a new policy =
and
sets attr.sched_flags =3D SCHED_FLAG_KEEP_PARAMS?

In __sched_setscheduler(), if SCHED_FLAG_KEEP_PARAMS is set, the class
assignment p->sched_class =3D next_class is explicitly skipped.

However, because queue_flags includes DEQUEUE_CLASS, the newly modified
sched_change_begin() unconditionally invokes next_class->prepare_switch(rq,=
 p)
for the incoming class.

Because the task never actually transitions to next_class, does this leave
the prepared state dangling and resources leaked since there won't be a
matching cleanup or transition?

--=20
Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260725160513.5747=
[email protected]?part=3D4