Skip to content

Commit 0fb3cf6

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
bpf: use register liveness information for func_states_equal
Liveness analysis DFA computes a set of registers live before each instruction. Leverage this information to skip comparison of dead registers in func_states_equal(). This helps with convergance of iterator processing loops, as bpf_reg_state->live marks can't be used when loops are processed. This has certain performance impact for selftests, here is a veristat listing using `-f "insns_pct>5" -f "!insns<200"` selftests: File Program States (A) States (B) States (DIFF) -------------------- ----------------------------- ---------- ---------- -------------- arena_htab.bpf.o arena_htab_llvm 37 35 -2 (-5.41%) arena_htab_asm.bpf.o arena_htab_asm 37 33 -4 (-10.81%) arena_list.bpf.o arena_list_add 37 22 -15 (-40.54%) dynptr_success.bpf.o test_dynptr_copy 22 16 -6 (-27.27%) dynptr_success.bpf.o test_dynptr_copy_xdp 68 58 -10 (-14.71%) iters.bpf.o checkpoint_states_deletion 918 40 -878 (-95.64%) iters.bpf.o clean_live_states 136 66 -70 (-51.47%) iters.bpf.o iter_nested_deeply_iters 43 37 -6 (-13.95%) iters.bpf.o iter_nested_iters 72 62 -10 (-13.89%) iters.bpf.o iter_pass_iter_ptr_to_subprog 30 26 -4 (-13.33%) iters.bpf.o iter_subprog_iters 68 59 -9 (-13.24%) iters.bpf.o loop_state_deps2 35 32 -3 (-8.57%) iters_css.bpf.o iter_css_for_each 32 29 -3 (-9.38%) pyperf600_iter.bpf.o on_event 286 192 -94 (-32.87%) Total progs: 3578 Old success: 2061 New success: 2061 States diff min: -95.64% States diff max: 0.00% -100 .. -90 %: 1 -55 .. -45 %: 3 -45 .. -35 %: 2 -35 .. -25 %: 5 -20 .. -10 %: 12 -10 .. 0 %: 6 sched_ext: File Program States (A) States (B) States (DIFF) ----------------- ---------------------- ---------- ---------- --------------- bpf.bpf.o lavd_dispatch 8950 7065 -1885 (-21.06%) bpf.bpf.o lavd_init 516 480 -36 (-6.98%) bpf.bpf.o layered_dispatch 662 501 -161 (-24.32%) bpf.bpf.o layered_dump 298 237 -61 (-20.47%) bpf.bpf.o layered_init 523 423 -100 (-19.12%) bpf.bpf.o layered_init_task 24 22 -2 (-8.33%) bpf.bpf.o layered_runnable 151 125 -26 (-17.22%) bpf.bpf.o p2dq_dispatch 66 53 -13 (-19.70%) bpf.bpf.o p2dq_init 170 142 -28 (-16.47%) bpf.bpf.o refresh_layer_cpumasks 120 78 -42 (-35.00%) bpf.bpf.o rustland_init 37 34 -3 (-8.11%) bpf.bpf.o rustland_init 37 34 -3 (-8.11%) bpf.bpf.o rusty_select_cpu 125 108 -17 (-13.60%) scx_central.bpf.o central_dispatch 59 43 -16 (-27.12%) scx_central.bpf.o central_init 39 28 -11 (-28.21%) scx_nest.bpf.o nest_init 58 51 -7 (-12.07%) scx_pair.bpf.o pair_dispatch 142 111 -31 (-21.83%) scx_qmap.bpf.o qmap_dispatch 174 141 -33 (-18.97%) scx_qmap.bpf.o qmap_init 768 654 -114 (-14.84%) Total progs: 216 Old success: 186 New success: 186 States diff min: -35.00% States diff max: 0.00% -35 .. -25 %: 3 -25 .. -20 %: 6 -20 .. -15 %: 6 -15 .. -5 %: 7 -5 .. 0 %: 6 Signed-off-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 14c8552 commit 0fb3cf6

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

kernel/bpf/verifier.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18500,15 +18500,17 @@ static bool refsafe(struct bpf_verifier_state *old, struct bpf_verifier_state *c
1850018500
* the current state will reach 'bpf_exit' instruction safely
1850118501
*/
1850218502
static bool func_states_equal(struct bpf_verifier_env *env, struct bpf_func_state *old,
18503-
struct bpf_func_state *cur, enum exact_level exact)
18503+
struct bpf_func_state *cur, u32 insn_idx, enum exact_level exact)
1850418504
{
18505-
int i;
18505+
u16 live_regs = env->insn_aux_data[insn_idx].live_regs_before;
18506+
u16 i;
1850618507

1850718508
if (old->callback_depth > cur->callback_depth)
1850818509
return false;
1850918510

1851018511
for (i = 0; i < MAX_BPF_REG; i++)
18511-
if (!regsafe(env, &old->regs[i], &cur->regs[i],
18512+
if (((1 << i) & live_regs) &&
18513+
!regsafe(env, &old->regs[i], &cur->regs[i],
1851218514
&env->idmap_scratch, exact))
1851318515
return false;
1851418516

@@ -18529,6 +18531,7 @@ static bool states_equal(struct bpf_verifier_env *env,
1852918531
struct bpf_verifier_state *cur,
1853018532
enum exact_level exact)
1853118533
{
18534+
u32 insn_idx;
1853218535
int i;
1853318536

1853418537
if (old->curframe != cur->curframe)
@@ -18552,9 +18555,12 @@ static bool states_equal(struct bpf_verifier_env *env,
1855218555
* and all frame states need to be equivalent
1855318556
*/
1855418557
for (i = 0; i <= old->curframe; i++) {
18558+
insn_idx = i == old->curframe
18559+
? env->insn_idx
18560+
: old->frame[i + 1]->callsite;
1855518561
if (old->frame[i]->callsite != cur->frame[i]->callsite)
1855618562
return false;
18557-
if (!func_states_equal(env, old->frame[i], cur->frame[i], exact))
18563+
if (!func_states_equal(env, old->frame[i], cur->frame[i], insn_idx, exact))
1855818564
return false;
1855918565
}
1856018566
return true;

0 commit comments

Comments
 (0)