Skip to content

Commit 744742c

Browse files
committed
bpf: include verifier memory allocations in memcg statistics
This commit adds __GFP_ACCOUNT flag to verifier induced memory allocations. The intent is to account for all allocations reachable from BPF_PROG_LOAD command, which is needed to track verifier memory consumption in veristat. This includes allocations done in verifier.c, and some allocations in btf.c, functions in log.c do not allocate. There is also a utility function bpf_memcg_flags() which selectively adds GFP_ACCOUNT flag depending on the `cgroup.memory=nobpf` option. As far as I understand [1], the idea is to remove bpf_prog instances and maps from memcg accounting as these objects do not strictly belong to cgroup, hence it should not apply here. (btf_parse_fields() is reachable from both program load and map creation, but allocated record is not persistent as is freed as soon as map_check_btf() exits). [1] https://lore.kernel.org/all/[email protected]/ Signed-off-by: Eduard Zingerman <[email protected]>
1 parent 2d72dd1 commit 744742c

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

kernel/bpf/btf.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,7 +3443,8 @@ btf_find_graph_root(const struct btf *btf, const struct btf_type *pt,
34433443
node_field_name = strstr(value_type, ":");
34443444
if (!node_field_name)
34453445
return -EINVAL;
3446-
value_type = kstrndup(value_type, node_field_name - value_type, GFP_KERNEL | __GFP_NOWARN);
3446+
value_type = kstrndup(value_type, node_field_name - value_type,
3447+
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
34473448
if (!value_type)
34483449
return -ENOMEM;
34493450
id = btf_find_by_name_kind(btf, value_type, BTF_KIND_STRUCT);
@@ -3958,7 +3959,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
39583959
/* This needs to be kzalloc to zero out padding and unused fields, see
39593960
* comment in btf_record_equal.
39603961
*/
3961-
rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL | __GFP_NOWARN);
3962+
rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
39623963
if (!rec)
39633964
return ERR_PTR(-ENOMEM);
39643965

@@ -9019,15 +9020,15 @@ static struct bpf_cand_cache *populate_cand_cache(struct bpf_cand_cache *cands,
90199020
bpf_free_cands_from_cache(*cc);
90209021
*cc = NULL;
90219022
}
9022-
new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL);
9023+
new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL_ACCOUNT);
90239024
if (!new_cands) {
90249025
bpf_free_cands(cands);
90259026
return ERR_PTR(-ENOMEM);
90269027
}
90279028
/* strdup the name, since it will stay in cache.
90289029
* the cands->name points to strings in prog's BTF and the prog can be unloaded.
90299030
*/
9030-
new_cands->name = kmemdup_nul(cands->name, cands->name_len, GFP_KERNEL);
9031+
new_cands->name = kmemdup_nul(cands->name, cands->name_len, GFP_KERNEL_ACCOUNT);
90319032
bpf_free_cands(cands);
90329033
if (!new_cands->name) {
90339034
kfree(new_cands);
@@ -9111,7 +9112,7 @@ bpf_core_add_cands(struct bpf_cand_cache *cands, const struct btf *targ_btf,
91119112
continue;
91129113

91139114
/* most of the time there is only one candidate for a given kind+name pair */
9114-
new_cands = kmalloc(sizeof_cands(cands->cnt + 1), GFP_KERNEL);
9115+
new_cands = kmalloc(sizeof_cands(cands->cnt + 1), GFP_KERNEL_ACCOUNT);
91159116
if (!new_cands) {
91169117
bpf_free_cands(cands);
91179118
return ERR_PTR(-ENOMEM);
@@ -9228,7 +9229,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
92289229
/* ~4k of temp memory necessary to convert LLVM spec like "0:1:0:5"
92299230
* into arrays of btf_ids of struct fields and array indices.
92309231
*/
9231-
specs = kcalloc(3, sizeof(*specs), GFP_KERNEL);
9232+
specs = kcalloc(3, sizeof(*specs), GFP_KERNEL_ACCOUNT);
92329233
if (!specs)
92339234
return -ENOMEM;
92349235

@@ -9253,7 +9254,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
92539254
goto out;
92549255
}
92559256
if (cc->cnt) {
9256-
cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL);
9257+
cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL_ACCOUNT);
92579258
if (!cands.cands) {
92589259
err = -ENOMEM;
92599260
goto out;

kernel/bpf/verifier.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
14041404
goto out;
14051405

14061406
alloc_size = kmalloc_size_roundup(size_mul(new_n, size));
1407-
new_arr = krealloc(arr, alloc_size, GFP_KERNEL);
1407+
new_arr = krealloc(arr, alloc_size, GFP_KERNEL_ACCOUNT);
14081408
if (!new_arr) {
14091409
kfree(arr);
14101410
return NULL;
@@ -1421,7 +1421,7 @@ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
14211421
static int copy_reference_state(struct bpf_verifier_state *dst, const struct bpf_verifier_state *src)
14221422
{
14231423
dst->refs = copy_array(dst->refs, src->refs, src->acquired_refs,
1424-
sizeof(struct bpf_reference_state), GFP_KERNEL);
1424+
sizeof(struct bpf_reference_state), GFP_KERNEL_ACCOUNT);
14251425
if (!dst->refs)
14261426
return -ENOMEM;
14271427

@@ -1440,7 +1440,7 @@ static int copy_stack_state(struct bpf_func_state *dst, const struct bpf_func_st
14401440
size_t n = src->allocated_stack / BPF_REG_SIZE;
14411441

14421442
dst->stack = copy_array(dst->stack, src->stack, n, sizeof(struct bpf_stack_state),
1443-
GFP_KERNEL);
1443+
GFP_KERNEL_ACCOUNT);
14441444
if (!dst->stack)
14451445
return -ENOMEM;
14461446

@@ -1761,7 +1761,7 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state,
17611761
for (i = 0; i <= src->curframe; i++) {
17621762
dst = dst_state->frame[i];
17631763
if (!dst) {
1764-
dst = kzalloc(sizeof(*dst), GFP_KERNEL);
1764+
dst = kzalloc(sizeof(*dst), GFP_KERNEL_ACCOUNT);
17651765
if (!dst)
17661766
return -ENOMEM;
17671767
dst_state->frame[i] = dst;
@@ -2033,7 +2033,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env,
20332033
struct bpf_verifier_stack_elem *elem;
20342034
int err;
20352035

2036-
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL);
2036+
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL_ACCOUNT);
20372037
if (!elem)
20382038
goto err;
20392039

@@ -2800,7 +2800,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env,
28002800
struct bpf_verifier_stack_elem *elem;
28012801
struct bpf_func_state *frame;
28022802

2803-
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL);
2803+
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL_ACCOUNT);
28042804
if (!elem)
28052805
goto err;
28062806

@@ -2828,7 +2828,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env,
28282828
elem->st.in_sleepable = is_sleepable;
28292829
elem->st.insn_hist_start = env->cur_state->insn_hist_end;
28302830
elem->st.insn_hist_end = elem->st.insn_hist_start;
2831-
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
2831+
frame = kzalloc(sizeof(*frame), GFP_KERNEL_ACCOUNT);
28322832
if (!frame)
28332833
goto err;
28342834
init_func_state(env, frame,
@@ -3180,7 +3180,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
31803180
return -EINVAL;
31813181
}
31823182

3183-
tab = kzalloc(sizeof(*tab), GFP_KERNEL);
3183+
tab = kzalloc(sizeof(*tab), GFP_KERNEL_ACCOUNT);
31843184
if (!tab)
31853185
return -ENOMEM;
31863186
prog_aux->kfunc_tab = tab;
@@ -3196,7 +3196,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
31963196
return 0;
31973197

31983198
if (!btf_tab && offset) {
3199-
btf_tab = kzalloc(sizeof(*btf_tab), GFP_KERNEL);
3199+
btf_tab = kzalloc(sizeof(*btf_tab), GFP_KERNEL_ACCOUNT);
32003200
if (!btf_tab)
32013201
return -ENOMEM;
32023202
prog_aux->kfunc_btf_tab = btf_tab;
@@ -10292,7 +10292,7 @@ static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int calls
1029210292
}
1029310293

1029410294
caller = state->frame[state->curframe];
10295-
callee = kzalloc(sizeof(*callee), GFP_KERNEL);
10295+
callee = kzalloc(sizeof(*callee), GFP_KERNEL_ACCOUNT);
1029610296
if (!callee)
1029710297
return -ENOMEM;
1029810298
state->frame[state->curframe + 1] = callee;
@@ -17629,17 +17629,18 @@ static int check_cfg(struct bpf_verifier_env *env)
1762917629
int *insn_stack, *insn_state, *insn_postorder;
1763017630
int ex_insn_beg, i, ret = 0;
1763117631

17632-
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
17632+
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
1763317633
if (!insn_state)
1763417634
return -ENOMEM;
1763517635

17636-
insn_stack = env->cfg.insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
17636+
insn_stack = env->cfg.insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
1763717637
if (!insn_stack) {
1763817638
kvfree(insn_state);
1763917639
return -ENOMEM;
1764017640
}
1764117641

17642-
insn_postorder = env->cfg.insn_postorder = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
17642+
insn_postorder = env->cfg.insn_postorder =
17643+
kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
1764317644
if (!insn_postorder) {
1764417645
kvfree(insn_state);
1764517646
kvfree(insn_stack);
@@ -17773,7 +17774,7 @@ static int check_btf_func_early(struct bpf_verifier_env *env,
1777317774
urecord = make_bpfptr(attr->func_info, uattr.is_kernel);
1777417775
min_size = min_t(u32, krec_size, urec_size);
1777517776

17776-
krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL | __GFP_NOWARN);
17777+
krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1777717778
if (!krecord)
1777817779
return -ENOMEM;
1777917780

@@ -17873,7 +17874,7 @@ static int check_btf_func(struct bpf_verifier_env *env,
1787317874
urecord = make_bpfptr(attr->func_info, uattr.is_kernel);
1787417875

1787517876
krecord = prog->aux->func_info;
17876-
info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL | __GFP_NOWARN);
17877+
info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1787717878
if (!info_aux)
1787817879
return -ENOMEM;
1787917880

@@ -17959,7 +17960,7 @@ static int check_btf_line(struct bpf_verifier_env *env,
1795917960
* pass in a smaller bpf_line_info object.
1796017961
*/
1796117962
linfo = kvcalloc(nr_linfo, sizeof(struct bpf_line_info),
17962-
GFP_KERNEL | __GFP_NOWARN);
17963+
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1796317964
if (!linfo)
1796417965
return -ENOMEM;
1796517966

@@ -19306,7 +19307,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
1930619307
* When looping the sl->state.branches will be > 0 and this state
1930719308
* will not be considered for equivalence until branches == 0.
1930819309
*/
19309-
new_sl = kzalloc(sizeof(struct bpf_verifier_state_list), GFP_KERNEL);
19310+
new_sl = kzalloc(sizeof(struct bpf_verifier_state_list), GFP_KERNEL_ACCOUNT);
1931019311
if (!new_sl)
1931119312
return -ENOMEM;
1931219313
env->total_states++;
@@ -22795,13 +22796,13 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
2279522796
env->prev_linfo = NULL;
2279622797
env->pass_cnt++;
2279722798

22798-
state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL);
22799+
state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL_ACCOUNT);
2279922800
if (!state)
2280022801
return -ENOMEM;
2280122802
state->curframe = 0;
2280222803
state->speculative = false;
2280322804
state->branches = 1;
22804-
state->frame[0] = kzalloc(sizeof(struct bpf_func_state), GFP_KERNEL);
22805+
state->frame[0] = kzalloc(sizeof(struct bpf_func_state), GFP_KERNEL_ACCOUNT);
2280522806
if (!state->frame[0]) {
2280622807
kfree(state);
2280722808
return -ENOMEM;
@@ -23027,7 +23028,7 @@ static void print_verification_stats(struct bpf_verifier_env *env)
2302723028
int bpf_prog_ctx_arg_info_init(struct bpf_prog *prog,
2302823029
const struct bpf_ctx_arg_aux *info, u32 cnt)
2302923030
{
23030-
prog->aux->ctx_arg_info = kmemdup_array(info, cnt, sizeof(*info), GFP_KERNEL);
23031+
prog->aux->ctx_arg_info = kmemdup_array(info, cnt, sizeof(*info), GFP_KERNEL_ACCOUNT);
2303123032
prog->aux->ctx_arg_info_size = cnt;
2303223033

2303323034
return prog->aux->ctx_arg_info ? 0 : -ENOMEM;
@@ -23971,7 +23972,7 @@ static int compute_live_registers(struct bpf_verifier_env *env)
2397123972
* - repeat the computation while {in,out} fields changes for
2397223973
* any instruction.
2397323974
*/
23974-
state = kvcalloc(insn_cnt, sizeof(*state), GFP_KERNEL);
23975+
state = kvcalloc(insn_cnt, sizeof(*state), GFP_KERNEL_ACCOUNT);
2397523976
if (!state) {
2397623977
err = -ENOMEM;
2397723978
goto out;
@@ -24045,7 +24046,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2404524046
/* 'struct bpf_verifier_env' can be global, but since it's not small,
2404624047
* allocate/free it every time bpf_check() is called
2404724048
*/
24048-
env = kvzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL);
24049+
env = kvzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL_ACCOUNT);
2404924050
if (!env)
2405024051
return -ENOMEM;
2405124052

@@ -24235,7 +24236,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2423524236
/* if program passed verifier, update used_maps in bpf_prog_info */
2423624237
env->prog->aux->used_maps = kmalloc_array(env->used_map_cnt,
2423724238
sizeof(env->used_maps[0]),
24238-
GFP_KERNEL);
24239+
GFP_KERNEL_ACCOUNT);
2423924240

2424024241
if (!env->prog->aux->used_maps) {
2424124242
ret = -ENOMEM;
@@ -24250,7 +24251,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2425024251
/* if program passed verifier, update used_btfs in bpf_prog_aux */
2425124252
env->prog->aux->used_btfs = kmalloc_array(env->used_btf_cnt,
2425224253
sizeof(env->used_btfs[0]),
24253-
GFP_KERNEL);
24254+
GFP_KERNEL_ACCOUNT);
2425424255
if (!env->prog->aux->used_btfs) {
2425524256
ret = -ENOMEM;
2425624257
goto err_release_maps;

0 commit comments

Comments
 (0)