summaryrefslogtreecommitdiff
path: root/kernel/bpf/btf.c
diff options
context:
space:
mode:
authorAndrii Nakryiko <andrii@kernel.org>2025-06-13 10:29:46 -0700
committerAndrii Nakryiko <andrii@kernel.org>2025-06-13 10:44:17 -0700
commite4c8f96adeb29a98f7848ee793085765cdede64c (patch)
treea15bfe787ed40376e958dbae96939b0598409308 /kernel/bpf/btf.c
parentccefa19335a0b81f11b0856e951ca909445b3783 (diff)
parent67cdcc405b46c13446d6d220a108daa2f8de3436 (diff)
Merge branch 'veristat-memory-accounting-for-bpf-programs'
Eduard Zingerman says: ==================== veristat: memory accounting for bpf programs When working on the verifier, it is sometimes interesting to know how a particular change affects memory consumption. This patch-set modifies veristat to provide such information. As a collateral, kernel needs an update to make allocations reachable from BPF program load accountable in memcg statistics. Here is a sample output: Program Peak states Peak memory (MiB) --------------- ----------- ----------------- lavd_select_cpu 2153 43 lavd_enqueue 1982 41 lavd_dispatch 3480 28 Technically, this is implemented by creating and entering a new cgroup at the start of veristat execution. The difference between values from cgroup "memory.peak" file before and after bpf_object__load() is used as a metric. To minimize measurements jitter data is collected in megabytes. Changelog: v2: https://lore.kernel.org/bpf/20250612130835.2478649-1-eddyz87@gmail.com/ v2 -> v3: - bpf_verifier_state->jmp_history and bpf_verifier_env->explored_states allocations are switched from GFP_USER to GFP_KERNEL_ACCOUNT (Andrii, Alexei); - veristat.c:STR macro removed, PATH_MAX-1 == 4095 is hard-coded in scanf format strings (Andrii); - env->{orig,stat}_cgroup size changed to PATH_MAX (Andrii); - snprintf_trunc() is removed, flag -Wno-format-truncation is added to CFLAGS for veristat.o when compiled with gcc; v1: https://lore.kernel.org/bpf/20250605230609.1444980-1-eddyz87@gmail.com/ v1 -> v2: - a single cgroup, created at the beginning of execution, is now used for measurements (Andrii, Mykyta); - cgroup namespace is not created, as it turned out to be useless (Andrii); - veristat no longer mounts cgroup fs or changes subtree_control, instead it looks for an existing mount point and reports an error if memory.peak file can't be opened (Andrii, Alexei); - if 'mem_peak' statistics is not enabled, veristat skips cgroup setup; - code sharing with cgroup_helpers.c was considered but was decided against to simplify veristat github sync. ==================== Link: https://patch.msgid.link/20250613072147.3938139-1-eddyz87@gmail.com Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Diffstat (limited to 'kernel/bpf/btf.c')
-rw-r--r--kernel/bpf/btf.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 1d2cf898e21e..682acb1ed234 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -3443,7 +3443,8 @@ btf_find_graph_root(const struct btf *btf, const struct btf_type *pt,
node_field_name = strstr(value_type, ":");
if (!node_field_name)
return -EINVAL;
- value_type = kstrndup(value_type, node_field_name - value_type, GFP_KERNEL | __GFP_NOWARN);
+ value_type = kstrndup(value_type, node_field_name - value_type,
+ GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
if (!value_type)
return -ENOMEM;
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
/* This needs to be kzalloc to zero out padding and unused fields, see
* comment in btf_record_equal.
*/
- rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL | __GFP_NOWARN);
+ rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
if (!rec)
return ERR_PTR(-ENOMEM);
@@ -9019,7 +9020,7 @@ static struct bpf_cand_cache *populate_cand_cache(struct bpf_cand_cache *cands,
bpf_free_cands_from_cache(*cc);
*cc = NULL;
}
- new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL);
+ new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL_ACCOUNT);
if (!new_cands) {
bpf_free_cands(cands);
return ERR_PTR(-ENOMEM);
@@ -9027,7 +9028,7 @@ static struct bpf_cand_cache *populate_cand_cache(struct bpf_cand_cache *cands,
/* strdup the name, since it will stay in cache.
* the cands->name points to strings in prog's BTF and the prog can be unloaded.
*/
- new_cands->name = kmemdup_nul(cands->name, cands->name_len, GFP_KERNEL);
+ new_cands->name = kmemdup_nul(cands->name, cands->name_len, GFP_KERNEL_ACCOUNT);
bpf_free_cands(cands);
if (!new_cands->name) {
kfree(new_cands);
@@ -9111,7 +9112,7 @@ bpf_core_add_cands(struct bpf_cand_cache *cands, const struct btf *targ_btf,
continue;
/* most of the time there is only one candidate for a given kind+name pair */
- new_cands = kmalloc(sizeof_cands(cands->cnt + 1), GFP_KERNEL);
+ new_cands = kmalloc(sizeof_cands(cands->cnt + 1), GFP_KERNEL_ACCOUNT);
if (!new_cands) {
bpf_free_cands(cands);
return ERR_PTR(-ENOMEM);
@@ -9228,7 +9229,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
/* ~4k of temp memory necessary to convert LLVM spec like "0:1:0:5"
* into arrays of btf_ids of struct fields and array indices.
*/
- specs = kcalloc(3, sizeof(*specs), GFP_KERNEL);
+ specs = kcalloc(3, sizeof(*specs), GFP_KERNEL_ACCOUNT);
if (!specs)
return -ENOMEM;
@@ -9253,7 +9254,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
goto out;
}
if (cc->cnt) {
- cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL);
+ cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL_ACCOUNT);
if (!cands.cands) {
err = -ENOMEM;
goto out;