STRUCT SCHED_EXT_OPS_CID(9)
π
struct sched_ext_ops_cid(9) β like, the cid-flavored twin of struct sched_ext_ops
okay so real talk, bestie: you're in the Kernel API Manual, section 9, and this page is all about struct sched_ext_ops_cid β the cid-form alternative to struct sched_ext_ops. it's giving "same energy, different vocabulary" and honestly? iconic. β¨
πΈ NAME πΈ
struct sched_ext_ops_cid β the cid-form alternative to struct sched_ext_ops. no cap, that's literally the whole name. π
π¦ SYNOPSIS π¦
struct sched_ext_ops_cid {
s32 (*select_cid)(struct task_struct *p, s32 prev_cid, u64 wake_flags);
void (*enqueue)(struct task_struct *p, u64 enq_flags);
void (*dequeue)(struct task_struct *p, u64 deq_flags);
void (*dispatch)(s32 cid, struct task_struct *prev);
void (*tick)(struct task_struct *p);
void (*runnable)(struct task_struct *p, u64 enq_flags);
void (*running)(struct task_struct *p);
void (*stopping)(struct task_struct *p, bool runnable);
void (*quiescent)(struct task_struct *p, u64 deq_flags);
bool (*yield)(struct task_struct *from, struct task_struct *to);
bool (*core_sched_before)(struct task_struct *a, struct task_struct *b);
void (*set_weight)(struct task_struct *p, u32 weight);
void (*set_cmask)(struct task_struct *p, const struct scx_cmask *cmask__arena);
void (*update_idle)(s32 cid, bool idle);
s32 (*init_task)(struct task_struct *p, struct scx_init_task_args *args);
void (*exit_task)(struct task_struct *p, struct scx_exit_task_args *args);
void (*enable)(struct task_struct *p, struct scx_enable_args *args);
void (*disable)(struct task_struct *p);
void (*dump)(struct scx_dump_ctx *ctx);
void (*dump_cid)(struct scx_dump_ctx *ctx, s32 cid, bool idle);
void (*dump_task)(struct scx_dump_ctx *ctx, struct task_struct *p);
#ifdef CONFIG_EXT_GROUP_SCHED;
s32 (*cpuctl_init)(struct cgroup *cgrp, struct scx_cgroup_init_args *args);
void (*cpuctl_exit)(struct cgroup *cgrp);
s32 (*cpuctl_prep_move)(struct task_struct *p, struct cgroup *from, struct cgroup *to);
void (*cpuctl_move)(struct task_struct *p, struct cgroup *from, struct cgroup *to);
void (*cpuctl_cancel_move)(struct task_struct *p, struct cgroup *from, struct cgroup *to);
void (*cpuctl_set_weight)(struct cgroup *cgrp, u32 weight);
void (*cpuctl_set_bandwidth)(struct cgroup *cgrp, u64 period_us, u64 quota_us, u64 burst_us);
void (*cpuctl_set_idle)(struct cgroup *cgrp, bool idle);
#endif ;
s32 (*sub_attach)(struct scx_sub_attach_args *args);
void (*sub_detach)(struct scx_sub_detach_args *args);
void (*sub_caps_updated)(const struct scx_cmask *cmask__arena, u64 caps);
void (*sub_ecaps_updated)(s32 cid, u64 before, u64 after);
void (*cid_online)(s32 cid);
void (*cid_offline)(s32 cid);
s32 (*init_cids)(void);
s32 (*init)(void);
void (*exit)(struct scx_exit_info *info);
u32 dispatch_max_batch;
u64 flags;
u32 timeout_ms;
u32 exit_dump_len;
u64 hotplug_seq;
u32 cid_shard_size;
u32 rescue_bandwidth_ppt;
u32 rescue_quantum_us;
u64 sub_cgroup_id;
char name[SCX_OPS_NAME_LEN];
void *priv;
char __end[0];
};
β¨ Members β¨
okay this section is short but it's doing a LOT of heavy lifting, so pay attention bestie π«Ά
π Description π
So basically it mirrors struct sched_ext_ops, bestie β except wherever cpu/cpumask showed up, it's been swapped for cid/cmask where applicable. glow-up behavior, fr fr.
And here's the part that's lowkey the coolest: the layout up to and including priv matches sched_ext_ops byte-for-byte. And no, they're not just trusting vibes on that β it's verified by BUILD_BUG_ON checks at scx_init time π«‘ so shared field offsets work for both struct types in bpf_scx_init_member and bpf_scx_check_member. shared offsets = the friendship bracelet of structs, honestly.
Also!! The deprecated cpu_acquire/cpu_release callbacks that are hanging out at the tail of sched_ext_ops? They are omitted here entirely. gone. not invited. π
π Differences from sched_ext_ops π
select_cpu->select_cid(returns cid)dispatch->dispatch(cpu arg is now cid)update_idle->update_idle(cpu arg is now cid)set_cpumask->set_cmask(cmask instead of cpumask)enable->enable(takes structscx_enable_args)cpu_online->cid_onlinecpu_offline->cid_offlinedump_cpu->dump_cidcgroup_*->cpuctl_*(they track the cgroup cpu controller)cpu_acquire/cpu_release-> not present (deprecated insched_ext_ops)
β οΈ ok this part is important, don't scroll past it: BPF schedulers using this type cannot call cpu-formscx_bpf_*kfuncs. use the cid-form variants instead, periodt. and it's not a suggestion either β it's enforced at BPF verifier time viascx_kfunc_context_filterbranching onprog->aux->st_ops. so like... the verifier will simply know. π
For the actual callback documentation, go read sched_ext_ops β it's all there, she's the main character, this one's the remix. π
π SEE ALSO π
Kernel file ./kernel/sched/ext/internal.h scx_add_event(9), __scx_add_event(9), struct scx_enable_args(9), struct sched_ext_ops(9), scx_arena_to_kaddr(9), scx_kaddr_to_arena(9), DEFINE_SCX_COMPAT_MARKER(9), scx_root_protected_live(9), scx_root_protected(9), scx_bypass_dsp_enabled(9), scx_ops_sanitize_err(9), scx_has_subs(9), scx_task_sched(9), scx_task_sched_rcu(9), scx_task_on_sched(9), scx_prog_sched(9), scx_parent(9)
and that's the whole page, bestie π mwah π β sign-off time: this lil gem lives at ./kernel/sched/ext and it's dated October 2026. go forth and schedule things. π§ββοΈ slay β¨
π¦ 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