finish_dispatch(9)
π
finish_dispatch(9) β like, the Kernel API Manual page, bestie β¨
okay so picture this: it's giving "kernel scheduler lore" and honestly? iconic. this is the man page for finish_dispatch, straight out of the Kernel API Manual, and we're gonna get through it together. no cap. π«Ά
β¨ NAME β¨
finish_dispatch β asynchronously finish dispatching a task π«
πΈ SYNOPSIS πΈ
void finish_dispatch (struct scx_sched *sch , struct rq *rq , struct
task_struct *p , unsigned long qseq_at_dispatch , u64 dsq_id , u64 slice
, u64 vtime , u64 enq_flags );
like yes that's a lot of parameters. we're gonna go through every single one. hydrate first. π
π ARGUMENTS π
schβ the scheduler. the main character, obviously πrqβ the current rq, and heads up bestie: it's locked πpβ the task that's finishing up its dispatching moment β¨qseq_at_dispatchβ theqseqfrom back whenpstarted getting dispatched. like a timestamp but for queueing, iykyk π°οΈdsq_idβ destination DSQ ID π―sliceβ the slice carried by the insert verdict. ngl,0keeps the current value πvtimeβ the vtime carried by the insert verdict β this one gets committed on PRIQ inserts βenq_flagsβSCX_ENQ_*. that's it, that's the description π¦
π DESCRIPTION π
so here's the vibe: dispatching to local DSQs might have to wait for queueing to finish, or it might need rq lock dancing π (yes that's a real thing in here, we don't make the rules). and we're like, absolutely not doing either of those while inside ops.dispatch, because that would be locking order inversion and we simply do not do that here π
so! dispatching gets split into two parts, periodt:
scx_bpf_dsq_insertβ called byops.dispatch, records the task and itsqseqπ- once
ops.dispatchreturns, this function gets called to finish up β¨
π¨ okay this part is so important, bestie, read it twice: there is no guarantee that p is still valid for dispatching β or even that it was valid in the first place π. make sure the task is still owned by the BPF scheduler, and claim the ownership before dispatching. fr fr, do not skip this.
π¦ SEE ALSO π¦
the friend group (aka the Kernel file ./kernel/sched/ext/ext.c, plus everyone in it):
scx_is_descendant(9), rq_is_open(9), scx_fill_cmask_scratch(9), scx_call_op_set_cpumask(9), nldsq_next_task(9), nldsq_cursor_next_task(9), nldsq_cursor_lost_task(9), scx_task_iter_start(9), scx_task_iter_unlock(9), scx_task_iter_relock(9), scx_task_iter_stop(9), scx_task_iter_next(9), scx_task_iter_next_locked(9), scx_dump_event(9), wait_ops_state(9), scx_cpu_valid(9), schedule_deferred(9), schedule_deferred_locked(9), dsq_insert_head(9), set_task_slice_keep_oob(9), scx_task_slice_ended(9), move_remote_task_to_local_dsq(9), unlink_dsq_and_switch_rq_lock(9), move_task_between_dsqs(9), dispatch_to_local_dsq(9), scx_prio_less(9), __scx_init_task(9), task_dead_and_done(9), scx_tg_sched(9), scx_tg_knob_sched(9), handle_lockup(9), scx_rcu_cpu_stall(9), scx_softlockup(9), scx_hardlockup(9), unbypass_renotify_idle(9), scx_bypass(9), scx_propagate_exit_irq_workfn(9), scx_flush_disable_work(9), print_scx_info(9), scx_bpf_dsq_insert___v2(9), __scx_bpf_dsq_insert_vtime(9), scx_bpf_dispatch_nr_slots(9), scx_bpf_dispatch_cancel(9), scx_bpf_dsq_move_to_local___v2(9), scx_bpf_dsq_move_set_slice(9), scx_bpf_dsq_move_set_vtime(9), scx_bpf_dsq_move(9), scx_bpf_dsq_move_vtime(9), scx_bpf_reenqueue_local(9), scx_bpf_create_dsq(9), scx_bpf_task_set_slice(9), scx_bpf_task_set_dsq_vtime(9), scx_bpf_kick_cpu(9), scx_bpf_kick_cid(9), scx_bpf_dsq_nr_queued(9), scx_bpf_destroy_dsq(9), bpf_iter_scx_dsq_new(9), bpf_iter_scx_dsq_next(9), bpf_iter_scx_dsq_destroy(9), scx_bpf_dsq_peek(9), scx_bpf_dsq_reenq(9), scx_bpf_reenqueue_local___v2(9), scx_bpf_exit_bstr(9), scx_bpf_error_bstr(9), scx_bpf_dump_bstr(9), scx_bpf_cpuperf_cap(9), scx_bpf_cidperf_cap(9), scx_bpf_cpuperf_cur(9), scx_bpf_cidperf_cur(9), scx_bpf_cpuperf_set(9), scx_bpf_cidperf_set(9), scx_bpf_nr_node_ids(9), scx_bpf_nr_cpu_ids(9), scx_bpf_nr_cids(9), scx_bpf_nr_online_cids(9), scx_bpf_online_cmask(9), scx_bpf_this_cid(9), scx_bpf_get_possible_cpumask(9), scx_bpf_get_online_cpumask(9), scx_bpf_put_cpumask(9), scx_bpf_task_running(9), scx_bpf_task_cpu(9), scx_bpf_task_cid(9), scx_bpf_locked_rq(9), scx_bpf_cpu_curr(9), scx_bpf_cid_curr(9), scx_bpf_tid_to_task(9), scx_bpf_now(9), scx_bpf_events(9), scx_bpf_task_cgroup(9)
π and that's the whole page, bestie! π it lives in ./kernel/sched/ext, dated October 2026 β save the date, screenshot it, put it on your fridge π mwah, go dispatch something responsibly π§ββοΈ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms