scx_lavd fails with “KF_IMPLICIT_ARGS … pahole < 1.26” even with pahole 1.30 — root cause is GCC vs Clang, not pahole version
Posting this in case others hit the same wall. Short version: the error message is misleading. It’s not really about your pahole version — it’s about which compiler built your kernel.
Symptom
On Fedora 44 with kernel-cachyos (and also reproduced with the stock Fedora kernel, same result), trying to run scx_lavd (or presumably any scx_* scheduler using recent kfuncs) fails with:
Error: the running kernel's BTF has malformed scx kfunc prototype(s): __scx_bpf_dsq_insert_vtime, scx_bpf_cpu_curr, scx_bpf_cpuperf_cur, ...
These kfuncs are KF_IMPLICIT_ARGS but their public BTF prototype
still carries the implicit 'struct bpf_prog_aux *' argument...
Fix: boot a kernel whose BTF was generated with pahole >= 1.26.
pahole --version on the system was v1.30 — well above the 1.26 threshold the error message references. Reinstalling kernel-modules-extra, regenerating BTF from a debuginfo vmlinux with local pahole, even fully rebuilding the kernel from the matching .src.rpm with pahole 1.30 present at build time — none of it changed the outcome. The generated BTF for scx_bpf_kick_cpu (and the other kfuncs listed) always still carried the extra implicit aux (struct bpf_prog_aux *) argument in its FUNC_PROTO, confirmed directly via:
sudo bpftool btf dump file /sys/kernel/btf/vmlinux | grep -A4 "scx_bpf_kick_cpu"
Actual root cause
Checked lib/Kconfig.debug in the matching kernel source tree:
config PAHOLE_HAS_BTF_TAG
def_bool PAHOLE_VERSION >= 123
depends on CC_IS_CLANG
PAHOLE_HAS_BTF_TAG — the config option that controls whether pahole is instructed to correctly encode/strip these implicit-argument kfunc prototypes — explicitly depends on CC_IS_CLANG. Both the stock Fedora kernel and kernel-cachyos (as shipped/built via the COPR) are built with GCC. Regardless of the pahole version present on the building machine, this Kconfig option silently stays disabled when the kernel is compiled with GCC, and the resulting BTF keeps the implicit argument — which is exactly what breaks scx_lavd (and likely other scx schedulers relying on KF_IMPLICIT_ARGS kfuncs) at load time.
Confirmed directly by rebuilding the same source tree, same .config, changing only the compiler:
cp /boot/config-<kernel-version> .config
make CC=clang LLVM=1 olddefconfig
scripts/config --file .config -s CC_IS_CLANG # -> y
scripts/config --file .config -s PAHOLE_HAS_BTF_TAG # -> y (was undef/n with GCC)
scripts/config --file .config -s DEBUG_INFO_BTF # -> y
With GCC (CC=gcc, the Fedora/CachyOS default), PAHOLE_HAS_BTF_TAG stays unset no matter the pahole version. With CC=clang LLVM=1, it flips to y immediately, using the exact same .config otherwise.
Fix
Rebuild the kernel with the LLVM/Clang toolchain instead of GCC:
make CC=clang LLVM=1 -j$(nproc)
make CC=clang LLVM=1 modules_install
make CC=clang LLVM=1 install
Clang/lld/llvm are already present as build dependencies for kernel-cachyos on Fedora (pulled in automatically via dnf builddep), so no extra packages are needed beyond what the src.rpm already requires.
Result — confirmed working
Full end-to-end confirmation on a locally rebuilt kernel-cachyos (7.1.3-cachyos1.fc44 source, rebuilt with CC=clang LLVM=1, same .config as the shipped COPR kernel otherwise):
$ sudo scx_lavd --performance
...
2026-07-12T12:51:55Z INFO scx_lavd: capacity bound: ...
Error: another sched_ext scheduler is already running
$ cat /sys/kernel/sched_ext/state
enabled
(The “another sched_ext scheduler is already running” message is expected/benign here — it means a previous scx_lavd instance from testing was still attached; sched_ext/state showing enabled is the actual confirmation that the BPF scheduler loaded and is active.)
So, to summarize the full path from broken to working:
-
Root cause of the original KF_IMPLICIT_ARGS error: PAHOLE_HAS_BTF_TAG in lib/Kconfig.debug depends on CC_IS_CLANG. Both stock Fedora and kernel-cachyos (as shipped via COPR) are built with GCC, so this stays off regardless of pahole version, and the BTF for kfuncs like scx_bpf_kick_cpu keeps the implicit struct bpf_prog_aux * argument, which scx_lavd rejects at load time.
-
Fix: rebuild with CC=clang LLVM=1 instead of GCC. This alone fixes the KF_IMPLICIT_ARGS BTF mismatch completely (confirmed via bpftool btf dump — the implicit aux argument is gone from the kfunc prototypes after rebuilding with Clang).
-
New issue that showed up after switching to Clang (on the stock Fedora kernel rebuild specifically): scx_lavd then failed to load with a generic -EINVAL at BPF_PROG_LOAD time (no verifier instruction dump, so a different failure mode than the original BTF mismatch — likely something struct_ops/ABI related, never fully root-caused on that build).
-
On kernel-cachyos specifically (same Clang rebuild approach, same script, same .config philosophy — just against the CachyOS source instead of stock Fedora): that -EINVAL did not appear. scx_lavd --performance loaded and attached cleanly, sched_ext/state reports enabled. Whatever caused the -EINVAL on the stock kernel rebuild, kernel-cachyos’s source/config apparently avoids it — possibly related to CachyOS’s own BORE/scheduler-related config choices, though this wasn’t independently isolated; it’s just an empirical result of rebuilding both the same way and only one working.
Practical takeaway if you’re on kernel-cachyos and want to run scx_lavd (or likely other KF_IMPLICIT_ARGS-dependent scx_* schedulers): rebuilding the COPR kernel locally with CC=clang LLVM=1 gets you a fully working setup. It’d be worth the COPR maintainers considering building with Clang/LLVM by default, since the target audience (gaming/BORE/scx users) is exactly the group most likely to hit this.
Why this matters for kernel-cachyos specifically
Since kernel-cachyos targets users who often want the latest scx_* schedulers (BORE is already patched in, sched_ext is a natural pairing), it might be worth considering building the COPR kernel with CC=clang LLVM=1 by default, or at minimum documenting this dependency — otherwise PAHOLE_HAS_BTF_TAG silently stays off and any scx scheduler relying on these kfuncs fails with an error message that (misleadingly) points at the pahole version instead of the compiler.
System: Fedora 44, kernel-cachyos 7.1.3-cachyos1, pahole 1.30 (dwarves-1.30-3.fc44), clang 22.1.8