Skip to content

Commit e9ded77

Browse files
bpf: Consolidate locks and reference state in verifier state
JIRA: https://issues.redhat.com/browse/RHEL-78201 commit 1995edc Author: Kumar Kartikeya Dwivedi <memxor@gmail.com> Date: Tue Dec 3 19:03:54 2024 -0800 bpf: Consolidate locks and reference state in verifier state Currently, state for RCU read locks and preemption is in bpf_verifier_state, while locks and pointer reference state remains in bpf_func_state. There is no particular reason to keep the latter in bpf_func_state. Additionally, it is copied into a new frame's state and copied back to the caller frame's state everytime the verifier processes a pseudo call instruction. This is a bit wasteful, given this state is global for a given verification state / path. Move all resource and reference related state in bpf_verifier_state structure in this patch, in preparation for introducing new reference state types in the future. Since we switch print_verifier_state and friends to print using vstate, we now need to explicitly pass in the verifier state from the caller along with the bpf_func_state, so modify the prototype and callers to do so. To ensure func state matches the verifier state when we're printing data, take in frame number instead of bpf_func_state pointer instead and avoid inconsistencies induced by the caller. Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20241204030400.208005-2-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
1 parent 8893938 commit e9ded77

File tree

3 files changed

+88
-91
lines changed

3 files changed

+88
-91
lines changed

include/linux/bpf_verifier.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,6 @@ struct bpf_func_state {
315315
u32 callback_depth;
316316

317317
/* The following fields should be last. See copy_func_state() */
318-
int acquired_refs;
319-
int active_locks;
320-
struct bpf_reference_state *refs;
321318
/* The state of the stack. Each element of the array describes BPF_REG_SIZE
322319
* (i.e. 8) bytes worth of stack memory.
323320
* stack[0] represents bytes [*(r10-8)..*(r10-1)]
@@ -370,6 +367,8 @@ struct bpf_verifier_state {
370367
/* call stack tracking */
371368
struct bpf_func_state *frame[MAX_CALL_FRAMES];
372369
struct bpf_verifier_state *parent;
370+
/* Acquired reference states */
371+
struct bpf_reference_state *refs;
373372
/*
374373
* 'branches' field is the number of branches left to explore:
375374
* 0 - all possible paths from this state reached bpf_exit or
@@ -419,9 +418,12 @@ struct bpf_verifier_state {
419418
u32 insn_idx;
420419
u32 curframe;
421420

422-
bool speculative;
421+
u32 acquired_refs;
422+
u32 active_locks;
423+
u32 active_preempt_locks;
423424
bool active_rcu_lock;
424-
u32 active_preempt_lock;
425+
426+
bool speculative;
425427
/* If this state was ever pointed-to by other state's loop_entry field
426428
* this flag would be set to true. Used to avoid freeing such states
427429
* while they are still in use.
@@ -980,8 +982,9 @@ const char *dynptr_type_str(enum bpf_dynptr_type type);
980982
const char *iter_type_str(const struct btf *btf, u32 btf_id);
981983
const char *iter_state_str(enum bpf_iter_state state);
982984

983-
void print_verifier_state(struct bpf_verifier_env *env,
984-
const struct bpf_func_state *state, bool print_all);
985-
void print_insn_state(struct bpf_verifier_env *env, const struct bpf_func_state *state);
985+
void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_verifier_state *vstate,
986+
u32 frameno, bool print_all);
987+
void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_state *vstate,
988+
u32 frameno);
986989

987990
#endif /* _LINUX_BPF_VERIFIER_H */

kernel/bpf/log.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,10 @@ static void print_reg_state(struct bpf_verifier_env *env,
753753
verbose(env, ")");
754754
}
755755

756-
void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_func_state *state,
757-
bool print_all)
756+
void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_verifier_state *vstate,
757+
u32 frameno, bool print_all)
758758
{
759+
const struct bpf_func_state *state = vstate->frame[frameno];
759760
const struct bpf_reg_state *reg;
760761
int i;
761762

@@ -843,11 +844,11 @@ void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_func_st
843844
break;
844845
}
845846
}
846-
if (state->acquired_refs && state->refs[0].id) {
847-
verbose(env, " refs=%d", state->refs[0].id);
848-
for (i = 1; i < state->acquired_refs; i++)
849-
if (state->refs[i].id)
850-
verbose(env, ",%d", state->refs[i].id);
847+
if (vstate->acquired_refs && vstate->refs[0].id) {
848+
verbose(env, " refs=%d", vstate->refs[0].id);
849+
for (i = 1; i < vstate->acquired_refs; i++)
850+
if (vstate->refs[i].id)
851+
verbose(env, ",%d", vstate->refs[i].id);
851852
}
852853
if (state->in_callback_fn)
853854
verbose(env, " cb");
@@ -864,7 +865,8 @@ static inline u32 vlog_alignment(u32 pos)
864865
BPF_LOG_MIN_ALIGNMENT) - pos - 1;
865866
}
866867

867-
void print_insn_state(struct bpf_verifier_env *env, const struct bpf_func_state *state)
868+
void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_state *vstate,
869+
u32 frameno)
868870
{
869871
if (env->prev_log_pos && env->prev_log_pos == env->log.end_pos) {
870872
/* remove new line character */
@@ -873,5 +875,5 @@ void print_insn_state(struct bpf_verifier_env *env, const struct bpf_func_state
873875
} else {
874876
verbose(env, "%d:", env->insn_idx);
875877
}
876-
print_verifier_state(env, state, false);
878+
print_verifier_state(env, vstate, frameno, false);
877879
}

0 commit comments

Comments
 (0)