The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH sched_ext/for-7.2] sched_ext: Replace tryget_task_struct() with get_task_struct()
@ 2026-05-11 19:19 Andrea Righi
  2026-05-11 19:34 ` Tejun Heo
  0 siblings, 1 reply; 2+ messages in thread
From: Andrea Righi @ 2026-05-11 19:19 UTC (permalink / raw)
  To: Tejun Heo, David Vernet, Changwoo Min; +Cc: Alice Ryhl, sched-ext, linux-kernel

The tryget_task_struct() calls in scx_sub_disable(),
scx_root_enable_workfn() and scx_sub_enable_workfn() can never fail at
the points they're invoked:

 - scx_root_enable_workfn() iterates over scx_tasks under scx_tasks_lock
   and rq lock. sched_ext_dead() removes tasks from scx_tasks under the
   same scx_tasks_lock before put_task_struct_rcu_user() runs in
   finish_task_switch(). So any task observed in scx_tasks must have
   usage > 0; put_task_struct_rcu_user() hasn't been called and the
   delayed_put_task_struct() callback that decrements usage cannot have
   been queued.

 - scx_sub_disable() and scx_sub_enable_workfn() iterate via
   css_task_iter, which takes a reference on each task in
   css_task_iter_next() and holds it until the next iter_next() call, so
   usage > 0 is guaranteed by the iter itself.

The actual filter for dead tasks is the SCX_TASK_DEAD check inside
scx_task_iter_next_locked(), not tryget; tryget only fails on zero
usage, a state that can't be reached for tasks visible to these iters.

Commit 54d1429e7180 ("sched_ext: Use SCX_TASK_READY test instead of
tryget_task_struct() during class switch") removed an analogous tryget
in the class-switch loop. Convert the remaining tryget calls to plain
get_task_struct() and update the comment in scx_root_enable_workfn()
that suggested tasks could be observed with zero @usage waiting for an
RCU grace period.

Link: https://lore.kernel.org/all/agCLBxHEUqWIepx8@google.com
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Andrea Righi <arighi@nvidia.com>
---
 kernel/sched/ext.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index b8dd3358959d7..64dfaf4dc5b2f 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -5933,14 +5933,11 @@ static void scx_sub_disable(struct scx_sched *sch)
 		WARN_ON_ONCE(!scx_task_on_sched(sch, p));
 
 		/*
-		 * If $p is about to be freed, nothing prevents $sch from
-		 * unloading before $p reaches sched_ext_free(). Disable and
-		 * exit $p right away.
+		 * @p is pinned by the iter: css_task_iter_next() takes a
+		 * reference and holds it until the next iter_next() call, so
+		 * @p->usage is guaranteed > 0.
 		 */
-		if (!tryget_task_struct(p)) {
-			scx_disable_and_exit_task(sch, p);
-			continue;
-		}
+		get_task_struct(p);
 
 		scx_task_iter_unlock(&sti);
 
@@ -7181,12 +7178,13 @@ static void scx_root_enable_workfn(struct kthread_work *work)
 	scx_task_iter_start(&sti, NULL);
 	while ((p = scx_task_iter_next_locked(&sti))) {
 		/*
-		 * @p may already be dead, have lost all its usages counts and
-		 * be waiting for RCU grace period before being freed. @p can't
-		 * be initialized for SCX in such cases and should be ignored.
+		 * @p is in scx_tasks under scx_tasks_lock, and SCX_TASK_DEAD
+		 * tasks are filtered by scx_task_iter_next_locked().
+		 * sched_ext_dead() removes @p from scx_tasks under the same
+		 * lock before put_task_struct_rcu_user() runs, so @p->usage
+		 * is guaranteed > 0 here.
 		 */
-		if (!tryget_task_struct(p))
-			continue;
+		get_task_struct(p);
 
 		/*
 		 * Set %INIT_BEGIN under the iter's rq lock so that a concurrent
@@ -7487,9 +7485,8 @@ static void scx_sub_enable_workfn(struct kthread_work *work)
 		if (p->scx.flags & SCX_TASK_SUB_INIT)
 			continue;
 
-		/* see scx_root_enable() */
-		if (!tryget_task_struct(p))
-			continue;
+		/* @p is pinned by the iter; see scx_sub_disable() */
+		get_task_struct(p);
 
 		if (!assert_task_ready_or_enabled(p)) {
 			ret = -EINVAL;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH sched_ext/for-7.2] sched_ext: Replace tryget_task_struct() with get_task_struct()
  2026-05-11 19:19 [PATCH sched_ext/for-7.2] sched_ext: Replace tryget_task_struct() with get_task_struct() Andrea Righi
@ 2026-05-11 19:34 ` Tejun Heo
  0 siblings, 0 replies; 2+ messages in thread
From: Tejun Heo @ 2026-05-11 19:34 UTC (permalink / raw)
  To: Andrea Righi
  Cc: David Vernet, Changwoo Min, Alice Ryhl, Emil Tsalapatis,
	sched-ext, linux-kernel

Hello,

On Mon, May 11, 2026 at 09:19:40PM +0200, Andrea Righi wrote:
> The tryget_task_struct() calls in scx_sub_disable(),
> scx_root_enable_workfn() and scx_sub_enable_workfn() can never fail at
> the points they're invoked:

Applied to sched_ext/for-7.2. Fixed the cited SHA in the description -
the analogous earlier change is b7d4b28db7da, not 54d1429e7180.

Thanks.

--
tejun

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-11 19:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11 19:19 [PATCH sched_ext/for-7.2] sched_ext: Replace tryget_task_struct() with get_task_struct() Andrea Righi
2026-05-11 19:34 ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox