diff options
| author | Tejun Heo <tj@kernel.org> | 2026-10-26 14:17:37 -1000 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-10-27 09:40:56 -1000 |
| commit | 006e9e9336b96964aafa4bb045e75077ee38f50b (patch) | |
| tree | 5b69769d0585473ce3eb70d3244ff0943bcb9fda /include/linux/timerqueue.h | |
| parent | 867d0ac6d730768610eae7fc41f5dd3b70b8d1a4 (diff) | |
sched_ext: Fix rescue served time disagreeing with the slice under proxy execution
Rescue measures served time as the rescuee's sum_exec_runtime minus a
snapshot taken at admission. Under proxy execution that measure follows the
wrong task. update_se() credits sum_exec_runtime to rq->curr, the mutex
owner that executes, while update_curr_scx() drains the slice of rq->donor
and charges its rescue. A rescuee can be either, so its served time and its
slice disagree in both directions.
As the owner running for another donor, the rescuee accrues served time that
drained no slice and charged no budget, and its rescue ends early. As the
donor, its rescue runs long:
1. the rescuee blocks on a mutex and the owner runs in its place
2. the owner's run drains the rescuee's slice and the budget, but not the
served time
3. the slice runs out with the rescue still open, and scx_rescue_keep()
restores a remainder that the owner's run didn't reduce
4. the owner keeps running on the rescue until it releases the mutex, past
the admitted slice and overdrawing the budget
Count served time in scx_rescue_charge() from the delta that drains the
slice. Charging the owner's run to the donor's rescue matches proxy
execution, which drains the donor's slice and accounts the cgroup time to
the donor for the owner's run.
scx_rescue_keep() also ignored the return of scx_set_task_slice(). The call
refuses the restore on a rescuee that escalation marked SCX_TASK_PROTECTED,
and the rescuee was kept with a zero slice and its protection set.
That refusal is now unreachable. Escalation sets the slice to the unserved
remainder before it protects the task. From then on every slice write a
scheduler can reach is refused. Only a sub-scheduler's task is rescued, and
sub-schedulers are cid-form, which rejects direct slice writes.
The slice then moves only by what update_curr_scx() drains, and that drain
charges the rescue by the same amount, so the slice runs out exactly when
the charge ends the rescue. WARN and end the rescue if the restore is
refused anyway.
Fixes: 5fd501744b10 ("sched_ext: Add bandwidth-limited rescue execution for stranded tasks")
Reported-by: Sashiko <sashiko-bot@kernel.org>
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
