Re: [PATCH sched_ext/for-7.4] sched_ext: Work around pahole 1.32 dropping scx_bpf_task_set_lazy_resched() from BTF
From: Andrea Righi
Date: Tue Sep 29 2026 - 15:20:13 EST
Hi Tejun,
On Tue, Sep 29, 2026 at 07:32:26AM -1000, Tejun Heo wrote:
> With clang and pahole 1.32, x86-64 vmlinux BTF lacks
> scx_bpf_task_set_lazy_resched() and sched_ext fails to initialize:
>
> sched_ext: Failed to register kfunc sets (-22)
>
> clang describes the lazy argument only after the prologue moves it into a
> callee-saved register, which pahole 1.32 rejects as not being the argument
> register. Released pahole is affected whatever the eventual fix. Keep the
> argument on the stack with barrier_data() so that its location names no
> register. OPTIMIZER_HIDE_VAR() would fix x86-64 but break arm64.
>
> Fixes: f8e5a4e3f3be ("sched_ext: Add lazy preemption support")
> Link: https://lore.kernel.org/r/20260925213619.2187751-1-yonghong.song@xxxxxxxxx
> Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
> ---
> kernel/sched/ext/ext.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -10136,6 +10136,11 @@ __bpf_kfunc bool scx_bpf_task_set_lazy_r
> {
> struct scx_sched *sch;
>
> + /*
> + * clang's register locations for @lazy make pahole 1.32 drop this kfunc
> + * from BTF. Keep @lazy in memory so its location names no register.
> + */
> + barrier_data(&lazy);
First of all thanks for figuring this out, it was really annoying, I've been
holding pahole to 1.31 because of this.
I also looked a bit and it seems to be triggered specifically by the bool type.
This is with clang 22.1.8 on x86_64 without barrier_data and only changing the
type:
bool movl %esi, %ebp -> dropped by pahole
u32 movl %esi, %ebp -> ok
u64 movq %rsi, %r15 -> ok
With u32 the generated code is identical to the bool case, but clang keeps the
RSI entry range, so pahole is happy.
Should we just change lazy to u32 (or use a u64 flags) instead of using
barrier_data()?
Thanks,
-Andrea
> guard(rcu)();
> sch = scx_prog_sched(aux);
> if (unlikely(!sch || !scx_task_on_sched(sch, p)))