Skip to content

Commit 638f5b9

Browse files
4astdavem330
authored andcommitted
bpf: reduce verifier memory consumption
the verifier got progressively smarter over time and size of its internal state grew as well. Time to reduce the memory consumption. Before: sizeof(struct bpf_verifier_state) = 6520 After: sizeof(struct bpf_verifier_state) = 896 It's done by observing that majority of BPF programs use little to no stack whereas verifier kept all of 512 stack slots ready always. Instead dynamically reallocate struct verifier state when stack access is detected. Runtime difference before vs after is within a noise. The number of processed instructions stays the same. Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3179698 commit 638f5b9

File tree

3 files changed

+305
-156
lines changed

3 files changed

+305
-156
lines changed

drivers/net/ethernet/netronome/nfp/bpf/verifier.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ nfp_bpf_goto_meta(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
7676

7777
static int
7878
nfp_bpf_check_exit(struct nfp_prog *nfp_prog,
79-
const struct bpf_verifier_env *env)
79+
struct bpf_verifier_env *env)
8080
{
81-
const struct bpf_reg_state *reg0 = &env->cur_state.regs[0];
81+
const struct bpf_reg_state *reg0 = cur_regs(env) + BPF_REG_0;
8282
u64 imm;
8383

8484
if (nfp_prog->act == NN_ACT_XDP)
@@ -144,9 +144,9 @@ nfp_bpf_check_stack_access(struct nfp_prog *nfp_prog,
144144

145145
static int
146146
nfp_bpf_check_ptr(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
147-
const struct bpf_verifier_env *env, u8 reg_no)
147+
struct bpf_verifier_env *env, u8 reg_no)
148148
{
149-
const struct bpf_reg_state *reg = &env->cur_state.regs[reg_no];
149+
const struct bpf_reg_state *reg = cur_regs(env) + reg_no;
150150
int err;
151151

152152
if (reg->type != PTR_TO_CTX &&

include/linux/bpf_verifier.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,19 @@ enum bpf_stack_slot_type {
8888

8989
#define BPF_REG_SIZE 8 /* size of eBPF register in bytes */
9090

91+
struct bpf_stack_state {
92+
struct bpf_reg_state spilled_ptr;
93+
u8 slot_type[BPF_REG_SIZE];
94+
};
95+
9196
/* state of the program:
9297
* type of all registers and stack info
9398
*/
9499
struct bpf_verifier_state {
95100
struct bpf_reg_state regs[MAX_BPF_REG];
96-
u8 stack_slot_type[MAX_BPF_STACK];
97-
struct bpf_reg_state spilled_regs[MAX_BPF_STACK / BPF_REG_SIZE];
98101
struct bpf_verifier_state *parent;
102+
int allocated_stack;
103+
struct bpf_stack_state *stack;
99104
};
100105

101106
/* linked list of verifier states used to prune search */
@@ -145,7 +150,7 @@ struct bpf_verifier_env {
145150
struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */
146151
int stack_size; /* number of states to be processed */
147152
bool strict_alignment; /* perform strict pointer alignment checks */
148-
struct bpf_verifier_state cur_state; /* current verifier state */
153+
struct bpf_verifier_state *cur_state; /* current verifier state */
149154
struct bpf_verifier_state_list **explored_states; /* search pruning optimization */
150155
const struct bpf_ext_analyzer_ops *analyzer_ops; /* external analyzer ops */
151156
void *analyzer_priv; /* pointer to external analyzer's private data */
@@ -159,6 +164,11 @@ struct bpf_verifier_env {
159164
struct bpf_verifer_log log;
160165
};
161166

167+
static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env)
168+
{
169+
return env->cur_state->regs;
170+
}
171+
162172
int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops,
163173
void *priv);
164174

0 commit comments

Comments
 (0)