Re: [PATCH v2] sched_ext: Document task ownership state machine

From: Kuba Piecuch

Date: Fri Mar 20 2026 - 14:16:48 EST


On Fri Mar 20, 2026 at 1:56 PM UTC, Kuba Piecuch wrote:
> On Thu Mar 5, 2026 at 6:29 AM UTC, Andrea Righi wrote:
>> + * - %SCX_OPSS_QUEUED:
>> + * Task is owned by the BPF scheduler. It's on a DSQ (dispatch queue)
>> + * and the BPF scheduler is responsible for dispatching it. A QSEQ
>
> The task doesn't have to be on a DSQ, it can be queued on some BPF data
> structure instead. Even if it is on a DSQ, its state depends on whether it's
> on a user DSQ (QUEUED) or a built-in DSQ, e.g. local (NONE).

My comment here is incorrect in that a task being on a user DSQ doesn't imply
it's in QUEUED state.
Now I actually think it's impossible for a task on _any_ DSQ to be in QUEUED
state, here's why:

In order to initially get on a DSQ a task must be inserted into one via
scx_bpf_dsq_insert(). That can happen in ops.{select_cpu,enqueue}()
(direct dispatch) or in ops.dispatch() ("normal" dispatch).

In the direct dispatch case, the task either:
* stays in NONE the whole time (ops.select_cpu()), or
* goes from QUEUEING to NONE and stays there (ops.enqueue()).

In the normal dispatch case, the task must be in QUEUED state for
finish_dispatch() to proceed, meaning it can't have been direct dispatched
earlier. Then, the task state goes through QUEUED -> DISPATCHING -> NONE
and stays there.

scx_bpf_dsq_insert() isn't the only way for a task to be inserted into a DSQ.
There's also scx_bpf_dsq_move(), but the task being moved must already be on
a DSQ, so it must be in state NONE, and scx_bpf_dsq_move() doesn't affect that
state.
There are also other mechanisms like SCX automatically inserting a task with
slice left into the local DSQ on preemption, but these also preserve the NONE
state.

So, QUEUED means the task is enqueued purely on the BPF side and isn't present
on any DSQ, either user-created or built-in.