All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: sched-ext@lists.linux.dev
Cc: David Vernet <void@manifault.com>,
	Andrea Righi <arighi@nvidia.com>,
	Changwoo Min <changwoo@igalia.com>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	David Dai <david.dai@linux.dev>,
	linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 12/17] sched_ext: Expire prev's slice in dispatch_one() under bypass
Date: Fri, 23 Oct 2026 07:56:03 -1000	[thread overview]
Message-ID: <20261023175608.4120910-13-tj@kernel.org> (raw)
In-Reply-To: <20261023175608.4120910-1-tj@kernel.org>

The next patch keeps a bypassed rescuee on the local DSQ and needs
dispatch_one() to keep it running too. dispatch_one()'s keep test refuses
any prev whose scheduler is bypassing, so another local task could run ahead
of the rescuee, even an escalated SCX_TASK_PROTECTED one. The test exists
because a cpu-form scheduler can write p->scx.slice directly from BPF, so
the slice can't be trusted under bypass.

The refusal doesn't hold anyway. Since 025b1bd41965 ("sched_ext: Implement
hierarchical bypass mode"), the host's ops.dispatch() runs while prev's
scheduler bypasses, and the post-dispatch test in scx_dispatch_sched() keeps
a queued prev with slice left without checking bypass. A task dispatched in
between waits behind prev until the next bypass tick zeroes the slice, at
most a tick.

Expire the slice before the keep test instead when prev's scheduler is
bypassing, as the bypass tick would. Neither test keeps prev on a zeroed
slice, so prev rotates. A kernel slice survives the expiry and keeps prev.
Only a sub-scheduler's task can hold one, and sub-schedulers are cid-form,
which rejects direct slice writes, so it can be trusted.

Drop the stale pointer to scx_disable_workfn(), update scx_bypass()'s
kerneldoc, and add a TODO noting that the bypass slice handling can be
cleaned up once the cpu form is deprecated and the kfuncs refuse slice
raises from a bypassing scheduler.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 kernel/sched/ext/ext.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 072153416256..6dc6ab2cb29c 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -3340,18 +3340,33 @@ static enum scx_dsp_verdict dispatch_one(struct rq *rq, struct task_struct *prev
 	if (prev->sched_class == &ext_sched_class) {
 		update_curr_scx(rq);
 
+		/*
+		 * Under bypass, @prev's slice can't be trusted as a cpu-form
+		 * scheduler can write it directly from BPF. Skipping the keep
+		 * below is not enough as the post-dispatch test in
+		 * scx_dispatch_sched() would keep @prev on the same slice.
+		 *
+		 * Expire it as the bypass tick would, so that neither test
+		 * keeps @prev on it and @prev rotates through the bypass
+		 * enqueue. A kernel slice is left alone and the keep below
+		 * keeps @prev on it, see %SCX_TASK_KERNEL_SLICE.
+		 *
+		 * TODO: Once the cpu form is deprecated and the kfuncs refuse
+		 * slice raises from a bypassing scheduler, slices can be
+		 * trusted under bypass. This expiry, the bypass tick's zeroing
+		 * and the related slice handling can then be cleaned up.
+		 */
+		if (scx_bypassing(scx_task_sched(prev), cpu))
+			expire_task_slice(prev);
+
 		/*
 		 * If @prev is runnable & has slice left, it has priority and
 		 * fetching more just increases latency for the fetched tasks.
 		 * Tell pick_task_scx() to keep running @prev. If the BPF
 		 * scheduler wants to handle this explicitly, it should
 		 * implement ->cpu_release().
-		 *
-		 * See scx_disable_workfn() for the explanation on the bypassing
-		 * test.
 		 */
-		if ((prev->scx.flags & SCX_TASK_QUEUED) && prev->scx.slice &&
-		    !scx_bypassing(scx_task_sched(prev), cpu)) {
+		if ((prev->scx.flags & SCX_TASK_QUEUED) && prev->scx.slice) {
 			verdict = SCX_DSP_PREV;
 			goto has_tasks;
 		}
@@ -6828,9 +6843,10 @@ static void unbypass_renotify_idle(struct rq *rq, struct scx_sched *pos,
  *
  * - ops.dispatch() is ignored.
  *
- * - dispatch_one() does not report %SCX_DSP_PREV on non-zero slice as slice
- *   can't be trusted. Whenever a tick triggers, the running task is rotated to
- *   the tail of the queue.
+ * - dispatch_one() expires prev's slice before its keep test as the slice can't
+ *   be trusted. Each tick does the same and rotates the running task to the
+ *   tail of the queue. A kernel slice is left alone, see
+ *   %SCX_TASK_KERNEL_SLICE.
  *
  * - pick_next_task() suppresses zero slice warning.
  *
-- 
2.56.0


  parent reply	other threads:[~2026-10-23 17:56 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-23 17:55 [PATCHSET v3 sched_ext/for-7.4] sched_ext: Fix bypassed sub-scheduler tasks stalling when the host lacks caps Tejun Heo
2026-10-23 17:55 ` [PATCH 01/17] sched_ext: Pack scx_ent_flags' multi-bit fields at the top Tejun Heo
2026-10-23 17:55 ` [PATCH 02/17] sched_ext: Clear holding_cpu where the claim is confirmed Tejun Heo
2026-10-23 17:55 ` [PATCH 03/17] sched_ext: Fix bypassed tasks stranded by the reenqueue limit Tejun Heo
2026-10-23 17:55 ` [PATCH 04/17] sched_ext: Fix bypassed tasks looping on a host without SCX_CAP_ENQ Tejun Heo
2026-10-23 18:50   ` sashiko-bot
2026-10-23 19:08     ` Tejun Heo
2026-10-23 17:55 ` [PATCH 05/17] sched_ext: Move refill_task_slice_dfl() below apply_slice_vtime() Tejun Heo
2026-10-23 17:55 ` [PATCH 06/17] sched_ext: Fix rescue served time disagreeing with the slice under proxy execution Tejun Heo
2026-10-23 17:55 ` [PATCH 07/17] sched_ext: Restore a rescuee's slice after ops.stopping() Tejun Heo
2026-10-23 17:55 ` [PATCH 08/17] sched_ext: Fix a cpu idling with a runnable rescuee Tejun Heo
2026-10-23 17:56 ` [PATCH 09/17] sched_ext: Mark the rescue grant as a kernel slice with SCX_TASK_KERNEL_SLICE Tejun Heo
2026-10-23 17:56 ` [PATCH 10/17] sched_ext: Refuse extending a kernel slice Tejun Heo
2026-10-23 17:56 ` [PATCH 11/17] sched_ext: Fix a cpu idling after put_prev_task_scx() queues its task on the local DSQ Tejun Heo
2026-10-23 17:56 ` Tejun Heo [this message]
2026-10-23 17:56 ` [PATCH 13/17] sched_ext: Fix bypassed tasks stalling when the host lacks SCX_CAP_BASE Tejun Heo
2026-10-23 19:02   ` sashiko-bot
2026-10-23 20:06     ` Tejun Heo
2026-10-23 17:56 ` [PATCH 14/17] sched_ext: Fix the bypass load balancer stranding tasks on cpus where " Tejun Heo
2026-10-23 17:56 ` [PATCH 15/17] sched_ext: Factor out bypass_lb_move() and insert with the donor DSQ unlocked Tejun Heo
2026-10-23 17:56 ` [PATCH 16/17] sched_ext: Let the bypass load balancer move tasks homed on other cpus Tejun Heo
2026-10-23 17:56 ` [PATCH 17/17] sched_ext: Fix queued bypassed tasks stalling when the host loses SCX_CAP_BASE Tejun Heo
2026-10-25 15:47   ` Andrea Righi
2026-10-26 21:31     ` Tejun Heo
2026-10-23 20:06 ` [PATCH 18/17] sched_ext: Fix use-after-free of a NONE rescuee leaving sched_ext Tejun Heo
2026-10-23 20:06 ` [PATCH 19/17] sched_ext: Fix the stall watchdog blaming a bypassing owner for a stuck task Tejun Heo
2026-10-25 15:52   ` Andrea Righi
2026-10-26 21:31     ` Tejun Heo
2026-10-23 20:10 ` [PATCH 20/17] sched_ext: Fix a lone IMMED task waiting behind a kept prev Tejun Heo

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=20261023175608.4120910-13-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=arighi@nvidia.com \
    --cc=changwoo@igalia.com \
    --cc=david.dai@linux.dev \
    --cc=emil@etsalapatis.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sched-ext@lists.linux.dev \
    --cc=void@manifault.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.