__scx_bpf_select_cpu_and(9)
π NAME π
__scx_bpf_select_cpu_and β arg-wrapped CPU selection, but make it cpumask π― (and yes bestie, this is a section 9 entry from the Kernel API Manual, we're in kernel-land now)
β¨ SYNOPSIS β¨
__bpf_kfunc s32 __scx_bpf_select_cpu_and (struct task_struct *p , const
struct cpumask *cpus_allowed , struct scx_bpf_select_cpu_and_args *args
, const struct bpf_prog_aux *aux );
okay so it's giving very long signature energy, but that's literally the whole point of this function, iykyk π«Ά
π ARGUMENTS π
pβ thetask_structwe're picking a CPU for. main character of the operation, honestly πcpus_allowedβ acpumaskof the CPUs that are actually allowed. the guest list, if you will ποΈargsβ a struct holding the rest of the arguments, because we ran out of room (more on that below π):args->prev_cpuβ the CPU thatpwas on previously, i.e. where it's coming fromargs->wake_flagsβ theSCX_WAKE_*flagsargs->flagsβ theSCX_PICK_IDLE*flags
auxβ the implicit BPF argument giving access tobpf_prog_aux, and it's hidden from BPF progs. you literally can't touch this one from your BPF program, it's for the kernel's eyes only π
π DESCRIPTION π
So here's the tea, bestie π: this is a wrapper kfunc that takes its arguments through a struct, and it does that for one extremely relatable reason β to work around BPF's 5 argument limit. like, five args, that's the whole budget, that's all BPF gives you π
BPF programs should not call this directly. instead use scx_bpf_select_cpu_and, which is provided as an inline wrapper in common.bpf.h. that's your entry point, periodt β¨
You can call it from ops.select_cpu, from ops.enqueue, or from an unlocked context such as a BPF test_run call β but only as long as built-in CPU selection is enabled, which means either:
ops.update_idleis missing, orSCX_OPS_KEEP_BUILTIN_IDLEis set
no built-in idle selection? then this vibe check fails, fr fr. make sure one of those two conditions holds π
Also super important matching situation: p, args->prev_cpu and args->wake_flags match ops.select_cpu. same crew, same semantics π§
πΈ What it gives back
It returns the selected idle CPU π« β and listen, that CPU gets automatically awakened upon returning from ops.select_cpu, and you can use it for direct dispatch. Or, if there's no idle CPU available, you get a negative value instead π that's the "nobody's home" answer.
π SEE ALSO π
Kernel file ./kernel/sched/ext/idle.c, plus the whole friend group:
scx_bpf_cpu_node(9)scx_bpf_select_cpu_dfl(9)scx_bpf_get_idle_cpumask_node(9)scx_bpf_get_idle_cpumask(9)scx_bpf_get_idle_smtmask_node(9)scx_bpf_get_idle_smtmask(9)scx_bpf_put_idle_cpumask(9)scx_bpf_test_and_clear_cpu_idle(9)scx_bpf_pick_idle_cpu_node(9)scx_bpf_pick_idle_cpu(9)scx_bpf_pick_any_cpu_node(9)scx_bpf_pick_any_cpu(9)
okay that's the whole page, slay π this one lives in ./kernel/sched/ext and it's dated October 2026 β so yeah, it's a little time-traveling queen from the future, we stan a forward-thinking manpage ππ
π¦ 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