summaryrefslogtreecommitdiff
path: root/include/linux/timerqueue.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-10-26 14:17:44 -1000
committerTejun Heo <tj@kernel.org>2026-10-27 09:40:56 -1000
commit947dd3eb80df8e83683182271d2782867befd333 (patch)
tree0838fa208163e4443a536a762eb640ff9b3e7e51 /include/linux/timerqueue.h
parentb9843b0399e807824020ccf7a47d06c19fbfa2d2 (diff)
sched_ext: Fix bypassed tasks stalling when the host lacks SCX_CAP_BASE
A bypassed task stalls on a cpu where its host lacks SCX_CAP_BASE. The host, the nearest ancestor that is not bypassing, runs a bypassing sub-scheduler's tasks through its per-cpu bypass DSQs. A cpu's dispatch only descends into schedulers holding BASE on it, so the host's bypass DSQ on such a cpu is never consumed until the host regains the cap. Resolve a bypassed task against its host at enqueue time. If the host lacks BASE on the cpu, send the task to rescue on that cpu, which runs it at bounded bandwidth without the host's dispatch having to reach it. The enqueue does not look above the host for an ancestor that holds BASE. That ancestor would run the task on cpus it never granted the host. With rescue disabled the task goes to the host's bypass DSQ as before and stalls there until the host regains BASE or the bypass ends, or until the stall watchdog ejects the host, which it blames for a task stuck on its DSQ. A task that must run on the cpu, migration-disabled or with a migration pending, is admitted to the local DSQ instead, as any insert of such a task is. Bypass also used to end a rescue, sending a preempted rescuee to the bypass DSQ with every other preempted task. Now that rescue is how a bypassed task runs while its host lacks BASE, keep a preempted rescuee on the local DSQ under bypass too. dispatch_one() also keeps such a rescuee running, as an earlier patch's bypass expiry leaves a kernel slice alone. The grant stays bounded by served time. A task scx_fail_parent() punted to its bypassing parent at NONE can be a rescuee too. switched_from_scx() ends its slice as it does for an enabled task, so that a NONE rescuee leaving sched_ext while running doesn't leave rq->scx.rescue.curr pointing at it. While at it, the rescue test in __scx_resolve_local_dsq() goes through the new scx_rescue_enabled() helper. v2: - The description notes that dispatch_one() keeps a bypassed rescuee too, through the new patch before this one (sashiko). - scx_rescue_keep()'s kerneldoc drops dispatch_one() declining a rescuee with slice left, which the new patch removes. v3: - With rescue disabled, a task that must run on the cpu is admitted to the local DSQ instead of waiting on the host's bypass DSQ. - The description names the stall watchdog as the way out for a task stuck without rescue. v4: - switched_from_scx() ends the slice of a NONE task, which can now be a rescuee (sashiko). - scx_punt_task()'s kerneldoc no longer says that switched_from_scx() skips a NONE task. - scx_bypass()'s kerneldoc and the ops.sub_ecaps_updated() doc say where a bypassed task can be besides the bypass DSQs. Fixes: 147d1885f390 ("sched_ext: Add the SCX_CAP_ENQ_IMMED cap") Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
Diffstat (limited to 'include/linux/timerqueue.h')
0 files changed, 0 insertions, 0 deletions