From 89749ecad75081bfc1375cb8ac5138a35139cb53 Mon Sep 17 00:00:00 2001 From: Changwoo Min Date: Tue, 22 Oct 2024 17:19:37 +0900 Subject: [PATCH] scx_lavd: fix/work around a verifier error Without this, the BPF verifier spits the following errors with *some* version of vmlinux.h. So added +1 to work around the problem. --------------- ; bpf_for(j, 0, 64) { @ main.bpf.c:1926 509: (bf) r1 = r8 ; R1_w=fp-32 R8_w=fp-32 refs=66,2035 510: (b4) w2 = 0 ; R2_w=0 refs=66,2035 511: (b4) w3 = 64 ; R3_w=64 refs=66,2035 512: (85) call bpf_iter_num_new#104189 ; R0=scalar() fp-32=iter_num(ref_id=2048,state=active,depth=0) refs=66,2035,2048 513: (bf) r1 = r8 ; R1=fp-32 R8=fp-32 refs=66,2035,2048 514: (85) call bpf_iter_num_next#104191 515: R0_w=rdonly_mem(id=2049,ref_obj_id=2048,sz=4) R6=scalar(id=2047,smin=smin32=0,smax=umax=smax32=umax32=7,var_off=(0x0; 0x7)) R7=scalar() R8=fp-32 R9=map_value(map=bpf_bpf.bss,ks=4,vs=4584,off=384,smin=smin32=0,smax=umax=smax32=umax32=3968,var_off=(0x0; 0xf80)) R10=fp0 fp-16=iter_num(ref_id=66,state=active,depth=1) fp-24=iter_num(ref_id=2035,state=active,depth=1) fp-32=iter_num(ref_id=2048,state=active,depth=1) fp-80=scalar(id=1) fp-88=map_value(map=.data.LAVD,ks=4,vs=1320,off=40,smin=smin32=0,smax=umax=smax32=umax32=1240,var_off=(0x0; 0x7f8)) fp-96=????0 fp-112=rcu_ptr_bpf_cpumask() fp-120=rcu_ptr_bpf_cpumask() fp-128=rcu_ptr_bpf_cpumask() fp-136=rcu_ptr_bpf_cpumask() refs=66,2035,2048 ; bpf_for(j, 0, 64) { @ main.bpf.c:1926 515: (15) if r0 == 0x0 goto pc+49 ; R0_w=rdonly_mem(id=2049,ref_obj_id=2048,sz=4) refs=66,2035,2048 516: (64) w6 <<= 6 ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=448,var_off=(0x0; 0x1c0)) refs=66,2035,2048 517: (61) r8 = *(u32 *)(r0 +0) ; R0=rdonly_mem(id=2049,ref_obj_id=2048,sz=4) R8_w=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff)) refs=66,2035,2048 518: (26) if w8 > 0x3f goto pc+46 ; R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=63,var_off=(0x0; 0x3f)) refs=66,2035,2048 ; if (cpumask & 0x1LLU << j) { @ main.bpf.c:1927 519: (bf) r1 = r7 ; R1_w=scalar(id=2053) R7=scalar(id=2053) refs=66,2035,2048 520: (7f) r1 >>= r8 ; R1_w=scalar() R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=63,var_off=(0x0; 0x3f)) refs=66,2035,2048 521: (57) r1 &= 1 ; R1_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1,var_off=(0x0; 0x1)) refs=66,2035,2048 522: (15) if r1 == 0x0 goto pc+38 ; R1_w=1 refs=66,2035,2048 ; cpu = (i * 64) + j; @ main.bpf.c:1928 523: (4c) w8 |= w6 ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=448,var_off=(0x0; 0x1c0)) R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=511,var_off=(0x0; 0x1ff)) refs=66,2035,2048 ; bpf_cpumask_set_cpu(cpu, cd_cpumask); @ main.bpf.c:1929 524: (bc) w1 = w8 ; R1_w=scalar(id=2054,smin=smin32=0,smax=umax=smax32=umax32=511,var_off=(0x0; 0x1ff)) R8_w=scalar(id=2054,smin=smin32=0,smax=umax=smax32=umax32=511,var_off=(0x0; 0x1ff)) refs=66,2035,2048 525: (79) r2 = *(u64 *)(r10 -88) ; R2_w=map_value(map=.data.LAVD,ks=4,vs=1320,off=40,smin=smin32=0,smax=umax=smax32=umax32=1240,var_off=(0x0; 0x7f8)) R10=fp0 fp-88=map_value(map=.data.LAVD,ks=4,vs=1320,off=40,smin=smin32=0,smax=umax=smax32=umax32=1240,var_off=(0x0; 0x7f8)) refs=66,2035,2048 526: (85) call bpf_cpumask_set_cpu#93595 invalid access to map value, value_size=1320 off=1280 size=48 R2 max value is outside of the allowed memory range processed 24200 insns (limit 1000000) max_states_per_insn 19 total_states 961 peak_states 789 mark_read 44 --------------- Signed-off-by: Changwoo Min --- scheds/rust/scx_lavd/src/bpf/util.bpf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scheds/rust/scx_lavd/src/bpf/util.bpf.c b/scheds/rust/scx_lavd/src/bpf/util.bpf.c index f8efaab..da7546b 100644 --- a/scheds/rust/scx_lavd/src/bpf/util.bpf.c +++ b/scheds/rust/scx_lavd/src/bpf/util.bpf.c @@ -16,7 +16,11 @@ private(LAVD) struct bpf_cpumask __kptr *big_cpumask; /* CPU mask for big CPUs * private(LAVD) struct bpf_cpumask __kptr *little_cpumask; /* CPU mask for little CPUs */ private(LAVD) struct bpf_cpumask __kptr *active_cpumask; /* CPU mask for active CPUs */ private(LAVD) struct bpf_cpumask __kptr *ovrflw_cpumask; /* CPU mask for overflow CPUs */ -private(LAVD) struct bpf_cpumask cpdom_cpumask[LAVD_CPDOM_MAX_NR]; /* CPU mask for each compute domain */ +private(LAVD) struct bpf_cpumask cpdom_cpumask[LAVD_CPDOM_MAX_NR+1]; /* CPU mask for each compute domain */ + /* + * I am sure that +1 shouldn't be necessary here. + * But it is added to workaround a verifier bug (?). + */ const volatile u64 nr_cpu_ids; /* maximum CPU IDs */ static volatile u64 nr_cpus_onln; /* current number of online CPUs */