mirror of
https://github.com/netdata/libbpf.git
synced 2026-11-08 10:50:15 +08:00
libbpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu maps
Add libbpf support for the BPF_F_CPU flag for percpu maps by embedding the cpu info into the high 32 bits of: 1. **flags**: bpf_map_lookup_elem_flags(), bpf_map__lookup_elem(), bpf_map_update_elem() and bpf_map__update_elem() 2. **opts->elem_flags**: bpf_map_lookup_batch() and bpf_map_update_batch() And the flag can be BPF_F_ALL_CPUS, but cannot be 'BPF_F_CPU | BPF_F_ALL_CPUS'. Behavior: * If the flag is BPF_F_ALL_CPUS, the update is applied across all CPUs. * If the flag is BPF_F_CPU, it updates value only to the specified CPU. * If the flag is BPF_F_CPU, lookup value only from the specified CPU. * lookup does not support BPF_F_ALL_CPUS. Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Leon Hwang <leon.hwang@linux.dev> Link: https://lore.kernel.org/r/20260107022022.12843-7-leon.hwang@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
1 parent
a6d7ceaaeb
commit
dc8673b28b
3 files changed
+36
-19
No files matched your search
+20
-6
@@ -10919,7 +10919,7 @@ bpf_object__find_map_fd_by_name(const struct bpf_object *obj, const char *name)
|
||||
}
|
||||
|
||||
static int validate_map_op(const struct bpf_map *map, size_t key_sz,
|
||||
size_t value_sz, bool check_value_sz)
|
||||
size_t value_sz, bool check_value_sz, __u64 flags)
|
||||
{
|
||||
if (!map_is_created(map)) /* map is not yet created */
|
||||
return -ENOENT;
|
||||
@@ -10946,6 +10946,20 @@ static int validate_map_op(const struct bpf_map *map, size_t key_sz,
|
||||
int num_cpu = libbpf_num_possible_cpus();
|
||||
size_t elem_sz = roundup(map->def.value_size, 8);
|
||||
|
||||
if (flags & (BPF_F_CPU | BPF_F_ALL_CPUS)) {
|
||||
if ((flags & BPF_F_CPU) && (flags & BPF_F_ALL_CPUS)) {
|
||||
pr_warn("map '%s': BPF_F_CPU and BPF_F_ALL_CPUS are mutually exclusive\n",
|
||||
map->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (map->def.value_size != value_sz) {
|
||||
pr_warn("map '%s': unexpected value size %zu provided for either BPF_F_CPU or BPF_F_ALL_CPUS, expected %u\n",
|
||||
map->name, value_sz, map->def.value_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (value_sz != num_cpu * elem_sz) {
|
||||
pr_warn("map '%s': unexpected value size %zu provided for per-CPU map, expected %d * %zu = %zd\n",
|
||||
map->name, value_sz, num_cpu, elem_sz, num_cpu * elem_sz);
|
||||
@@ -10970,7 +10984,7 @@ int bpf_map__lookup_elem(const struct bpf_map *map,
|
||||
{
|
||||
int err;
|
||||
|
||||
err = validate_map_op(map, key_sz, value_sz, true);
|
||||
err = validate_map_op(map, key_sz, value_sz, true, flags);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
@@ -10983,7 +10997,7 @@ int bpf_map__update_elem(const struct bpf_map *map,
|
||||
{
|
||||
int err;
|
||||
|
||||
err = validate_map_op(map, key_sz, value_sz, true);
|
||||
err = validate_map_op(map, key_sz, value_sz, true, flags);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
@@ -10995,7 +11009,7 @@ int bpf_map__delete_elem(const struct bpf_map *map,
|
||||
{
|
||||
int err;
|
||||
|
||||
err = validate_map_op(map, key_sz, 0, false /* check_value_sz */);
|
||||
err = validate_map_op(map, key_sz, 0, false /* check_value_sz */, flags);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
@@ -11008,7 +11022,7 @@ int bpf_map__lookup_and_delete_elem(const struct bpf_map *map,
|
||||
{
|
||||
int err;
|
||||
|
||||
err = validate_map_op(map, key_sz, value_sz, true);
|
||||
err = validate_map_op(map, key_sz, value_sz, true, flags);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
@@ -11020,7 +11034,7 @@ int bpf_map__get_next_key(const struct bpf_map *map,
|
||||
{
|
||||
int err;
|
||||
|
||||
err = validate_map_op(map, key_sz, 0, false /* check_value_sz */);
|
||||
err = validate_map_op(map, key_sz, 0, false /* check_value_sz */, 0);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
|
||||
Reference in new issue
Block a user