Skip to content

Commit

Permalink
scx_layered: Work around older kernels choking on function calls from…
Browse files Browse the repository at this point in the history
… sleepable progs

Verifier in older kernels choke on function calls from sleepable progs
triggering non-sensical RCU state error:

   frame1: R1_w=scalar(id=674,smin=smin32=0,smax=umax=smax32=umax32=51,var_off=(0x0; 0x3f)) R10=; return *llc_ptr;
  1072: (61) r0 = *(u32 *)(r2 +0)       ; frame1: R0_w=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff)) R2_w=map_value(map=bpf_bpf.rodata,ks=4,vs=9570,off=4400,smin=smin32=0,smax=umax=smax32=umax32=204,var_off=(0x0; 0xfc)) refs=13,647
  ; }
  1073: (95) exit
  bpf_rcu_read_unlock is missing
  processed 10663 insns (limit 1000000) max_states_per_insn 8 total_states 615 peak_states 281 mark_read 20
  -- END PROG LOAD LOG --

Work around by adding and using __always_inline variant of cpu_to_llc_id()
from layered_init(). Note that we can't switch everyone to __always_inline
as that can lead to verification failure due to ins limit.
  • Loading branch information
htejun committed Nov 8, 2024
1 parent 5280206 commit bb91ad0
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions scheds/rust/scx_layered/src/bpf/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ static __noinline u64 layer_dsq_id(u32 layer_id, u32 llc_id)
return (layer_id * nr_llcs) + llc_id;
}

static __noinline u32 cpu_to_llc_id(s32 cpu_id)
// XXX - cpu_to_llc_id() must not be inlined to not blow past ins limit when
// topo is enabled but older kernels get confused by RCU state when subprogs are
// called from sleepable functions. Use __always_inline variant from
// layered_init() and __noinline from everywhere else. Remove this once we can
// ignore the older kernels.
static __always_inline u32 __cpu_to_llc_id(s32 cpu_id)
{
const volatile u32 *llc_ptr;

Expand All @@ -116,6 +121,11 @@ static __noinline u32 cpu_to_llc_id(s32 cpu_id)
return *llc_ptr;
}

static __noinline u32 cpu_to_llc_id(u32 cpu_id)
{
return __cpu_to_llc_id(cpu_id);
}

u32 llc_node_id(u32 llc_id)
{
const volatile u32 *llc_ptr;
Expand Down Expand Up @@ -1777,7 +1787,7 @@ static s32 create_cache(u32 cache_id)
return -ENOENT;
}

llc_id = cpu_to_llc_id(cpu);
llc_id = __cpu_to_llc_id(cpu);
if (llc_id != cache_id)
continue;

Expand Down

0 comments on commit bb91ad0

Please sign in to comment.