bpf: add a new kfunc to return current bpf_map elements count
authorAnton Protopopov <aspsk@isovalent.com>
Thu, 6 Jul 2023 13:39:29 +0000 (13:39 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 6 Jul 2023 19:42:25 +0000 (12:42 -0700)
A bpf_map_sum_elem_count kfunc was added to simplify getting the sum of the map
per-cpu element counters. If a map doesn't implement the counter, then the
function will always return 0.

Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
Link: https://lore.kernel.org/r/20230706133932.45883-3-aspsk@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/map_iter.c

index b0fa190..d06d3b7 100644 (file)
@@ -93,7 +93,7 @@ static struct bpf_iter_reg bpf_map_reg_info = {
        .ctx_arg_info_size      = 1,
        .ctx_arg_info           = {
                { offsetof(struct bpf_iter__bpf_map, map),
-                 PTR_TO_BTF_ID_OR_NULL },
+                 PTR_TO_BTF_ID_OR_NULL | PTR_TRUSTED },
        },
        .seq_info               = &bpf_map_seq_info,
 };
@@ -193,3 +193,40 @@ static int __init bpf_map_iter_init(void)
 }
 
 late_initcall(bpf_map_iter_init);
+
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+                 "Global functions as their definitions will be in vmlinux BTF");
+
+__bpf_kfunc s64 bpf_map_sum_elem_count(struct bpf_map *map)
+{
+       s64 *pcount;
+       s64 ret = 0;
+       int cpu;
+
+       if (!map || !map->elem_count)
+               return 0;
+
+       for_each_possible_cpu(cpu) {
+               pcount = per_cpu_ptr(map->elem_count, cpu);
+               ret += READ_ONCE(*pcount);
+       }
+       return ret;
+}
+
+__diag_pop();
+
+BTF_SET8_START(bpf_map_iter_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_map_sum_elem_count, KF_TRUSTED_ARGS)
+BTF_SET8_END(bpf_map_iter_kfunc_ids)
+
+static const struct btf_kfunc_id_set bpf_map_iter_kfunc_set = {
+       .owner = THIS_MODULE,
+       .set   = &bpf_map_iter_kfunc_ids,
+};
+
+static int init_subsystem(void)
+{
+       return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_map_iter_kfunc_set);
+}
+late_initcall(init_subsystem);