Re: [PATCH sched_ext/for-7.1] sched_ext: Documentation: Add ops.dequeue() to task lifecycle

Emil Tsalapatis
2026-04-06T14:49:19Z

On Mon Apr 6, 2026 at 7:47 AM EDT, Andrea Righi wrote:
> Document ops.dequeue() in the sched_ext task lifecycle now that its
> semantics are well-defined.
>
> Also update the pseudo-code to use task_is_runnable() consistently and
> clarify the case where ops.dispatch() does not refill the time slice.
>
> Fixes: ebf1ccff79c4 ("sched_ext: Fix ops.dequeue() semantics")

Is the Fixes: tag appropriate here? It's not like the original patch
introduced a bug by fixing ops.dequeue().

Otherwise the state machine looks fine to me!

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>

> Signed-off-by: Andrea Righi <arighi@nvidia.com>
> ---
> Documentation/scheduler/sched-ext.rst | 24 +++++++++++++++---------
> 1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/scheduler/sched-ext.rst b/Documentation/scheduler/sched-ext.rst
> index 404b4e4c33f7e..9f03650abfeba 100644
> --- a/Documentation/scheduler/sched-ext.rst
> +++ b/Documentation/scheduler/sched-ext.rst
> @@ -422,23 +422,29 @@ by a sched_ext scheduler:
>
> ops.runnable(); /* Task becomes ready to run */
>
> - while (task is runnable) {
> + while (task_is_runnable(task)) {
> if (task is not in a DSQ && task->scx.slice == 0) {
> ops.enqueue(); /* Task can be added to a DSQ */
>
> - /* Any usable CPU becomes available */
> + /* Task property change (i.e., affinity, nice, etc.)? */
> + if (sched_change(task)) {
> + ops.dequeue(); /* Exiting BPF scheduler custody */
> + continue;
> + }
> + }
>
> - ops.dispatch(); /* Task is moved to a local DSQ */
> + /* Any usable CPU becomes available */
> +
> + ops.dispatch(); /* Task is moved to a local DSQ */
> + ops.dequeue(); /* Exiting BPF scheduler custody */
>
> - ops.dequeue(); /* Exiting BPF scheduler */
> - }
> ops.running(); /* Task starts running on its assigned CPU */
>
> - while task_is_runnable(p) {
> - while (task->scx.slice > 0 && task_is_runnable(p))
> - ops.tick(); /* Called every 1/HZ seconds */
> + while (task_is_runnable(task) && task->scx.slice > 0) {
> + ops.tick(); /* Called every 1/HZ seconds */
>
> - ops.dispatch(); /* task->scx.slice can be refilled */
> + if (task->scx.slice == 0)
> + ops.dispatch(); /* task->scx.slice can be refilled */
> }
>
> ops.stopping(); /* Task stops running (time slice expires or wait) */