A BPF scheduler implements arbitrary scheduling policies by providing a table of operations defined in struct sched_ext_ops. This structure allows the BPF program to hook into various stages of the task lifecycle, such as waking up, enqueuing, dispatching, and running tasks. A userland scheduling policy can also be implemented by using the BPF scheduler as a shim layer.
struct sched_ext_ops {
char [name][SCX_OPS_NAME_LEN];
u32 [dispatch_max_batch];
u64 [flags];
u32 [timeout_ms];
u32 [exit_dump_len];
u64 [hotplug_seq];
s32 (*[select_cpu])([struct task_struct] *p, s32 prev_cpu, u64 wake_flags);
void (*[enqueue])([struct task_struct] *p, u64 enq_flags);
void (*[dequeue])([struct task_struct] *p, u64 deq_flags);
void (*[dispatch])(s32 cpu, [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_cpumask])([struct task_struct] *p, const [struct cpumask] *cpumask);
void (*[update_idle])(s32 cpu, bool idle);
void (*[cpu_acquire])(s32 cpu, [struct scx_cpu_acquire_args] *args);
void (*[cpu_release])(s32 cpu, [struct scx_cpu_release_args] *args);
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);
void (*[disable])([struct task_struct] *p);
void (*[dump])([struct scx_dump_ctx] *ctx);
void (*[dump_cpu])([struct scx_dump_ctx] *ctx, s32 cpu, bool idle);
void (*[dump_task])([struct scx_dump_ctx] *ctx, [struct task_struct] *p);
#ifdef CONFIG_EXT_GROUP_SCHED
s32 (*[cgroup_init])([struct cgroup] *cgrp, [struct scx_cgroup_init_args] *args);
void (*[cgroup_exit])([struct cgroup] *cgrp);
s32 (*[cgroup_prep_move])([struct task_struct] *p, [struct cgroup] *from, [struct cgroup] *to);
void (*[cgroup_move])([struct task_struct] *p, [struct cgroup] *from, [struct cgroup] *to);
void (*[cgroup_cancel_move])([struct task_struct] *p, [struct cgroup] *from, [struct cgroup] *to);
void (*[cgroup_set_weight])([struct cgroup] *cgrp, u32 weight);
#endif
void (*[cpu_online])(s32 cpu);
void (*[cpu_offline])(s32 cpu);
s32 (*[init])(void);
void (*[exit])([struct scx_exit_info] *info);
};