Skip to content

Commit 4ba8533

Browse files
AsphalttKernel Patches Daemon
authored andcommitted
bpf: Introduce BPF_F_CPU and BPF_F_ALL_CPUS flags
Introduce BPF_F_CPU and BPF_F_ALL_CPUS flags and check them for following APIs: * 'map_lookup_elem()' * 'map_update_elem()' * 'generic_map_lookup_batch()' * 'generic_map_update_batch()' And, get the correct value size for these APIs. Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Leon Hwang <[email protected]>
1 parent 4586ea6 commit 4ba8533

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

include/linux/bpf.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3768,14 +3768,35 @@ int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char *
37683768
const char **linep, int *nump);
37693769
struct bpf_prog *bpf_prog_find_from_stack(void);
37703770

3771+
static inline bool bpf_map_supports_cpu_flags(enum bpf_map_type map_type)
3772+
{
3773+
return false;
3774+
}
3775+
37713776
static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 allowed_flags)
37723777
{
3773-
if (flags & ~allowed_flags)
3778+
u32 cpu;
3779+
3780+
if ((u32)flags & ~allowed_flags)
37743781
return -EINVAL;
37753782

37763783
if ((flags & BPF_F_LOCK) && !btf_record_has_field(map->record, BPF_SPIN_LOCK))
37773784
return -EINVAL;
37783785

3786+
if (!(flags & BPF_F_CPU) && flags >> 32)
3787+
return -EINVAL;
3788+
3789+
if (flags & (BPF_F_CPU | BPF_F_ALL_CPUS)) {
3790+
if (!bpf_map_supports_cpu_flags(map->map_type))
3791+
return -EINVAL;
3792+
if ((flags & BPF_F_CPU) && (flags & BPF_F_ALL_CPUS))
3793+
return -EINVAL;
3794+
3795+
cpu = flags >> 32;
3796+
if ((flags & BPF_F_CPU) && cpu >= num_possible_cpus())
3797+
return -ERANGE;
3798+
}
3799+
37793800
return 0;
37803801
}
37813802

include/uapi/linux/bpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,8 @@ enum {
13721372
BPF_NOEXIST = 1, /* create new element if it didn't exist */
13731373
BPF_EXIST = 2, /* update existing element */
13741374
BPF_F_LOCK = 4, /* spin_lock-ed map_lookup/map_update */
1375+
BPF_F_CPU = 8, /* cpu flag for percpu maps, upper 32-bit of flags is a cpu number */
1376+
BPF_F_ALL_CPUS = 16, /* update value across all CPUs for percpu maps */
13751377
};
13761378

13771379
/* flags for BPF_MAP_CREATE command */

kernel/bpf/syscall.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ bool bpf_map_write_active(const struct bpf_map *map)
133133
return atomic64_read(&map->writecnt) != 0;
134134
}
135135

136-
static u32 bpf_map_value_size(const struct bpf_map *map)
137-
{
138-
if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
139-
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
140-
map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY ||
141-
map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
136+
static u32 bpf_map_value_size(const struct bpf_map *map, u64 flags)
137+
{
138+
if (flags & (BPF_F_CPU | BPF_F_ALL_CPUS))
139+
return round_up(map->value_size, 8);
140+
else if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
141+
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
142+
map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY ||
143+
map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
142144
return round_up(map->value_size, 8) * num_possible_cpus();
143145
else if (IS_FD_MAP(map))
144146
return sizeof(u32);
@@ -1716,15 +1718,15 @@ static int map_lookup_elem(union bpf_attr *attr)
17161718
if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ))
17171719
return -EPERM;
17181720

1719-
err = bpf_map_check_op_flags(map, attr->flags, BPF_F_LOCK);
1721+
err = bpf_map_check_op_flags(map, attr->flags, BPF_F_LOCK | BPF_F_CPU);
17201722
if (err)
17211723
return err;
17221724

17231725
key = __bpf_copy_key(ukey, map->key_size);
17241726
if (IS_ERR(key))
17251727
return PTR_ERR(key);
17261728

1727-
value_size = bpf_map_value_size(map);
1729+
value_size = bpf_map_value_size(map, attr->flags);
17281730

17291731
err = -ENOMEM;
17301732
value = kvmalloc(value_size, GFP_USER | __GFP_NOWARN);
@@ -1791,7 +1793,7 @@ static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr)
17911793
goto err_put;
17921794
}
17931795

1794-
value_size = bpf_map_value_size(map);
1796+
value_size = bpf_map_value_size(map, attr->flags);
17951797
value = kvmemdup_bpfptr(uvalue, value_size);
17961798
if (IS_ERR(value)) {
17971799
err = PTR_ERR(value);
@@ -1987,11 +1989,12 @@ int generic_map_update_batch(struct bpf_map *map, struct file *map_file,
19871989
void *key, *value;
19881990
int err = 0;
19891991

1990-
err = bpf_map_check_op_flags(map, attr->batch.elem_flags, BPF_F_LOCK);
1992+
err = bpf_map_check_op_flags(map, attr->batch.elem_flags,
1993+
BPF_F_LOCK | BPF_F_CPU | BPF_F_ALL_CPUS);
19911994
if (err)
19921995
return err;
19931996

1994-
value_size = bpf_map_value_size(map);
1997+
value_size = bpf_map_value_size(map, attr->batch.elem_flags);
19951998

19961999
max_count = attr->batch.count;
19972000
if (!max_count)
@@ -2046,11 +2049,11 @@ int generic_map_lookup_batch(struct bpf_map *map,
20462049
u32 value_size, cp, max_count;
20472050
int err;
20482051

2049-
err = bpf_map_check_op_flags(map, attr->batch.elem_flags, BPF_F_LOCK);
2052+
err = bpf_map_check_op_flags(map, attr->batch.elem_flags, BPF_F_LOCK | BPF_F_CPU);
20502053
if (err)
20512054
return err;
20522055

2053-
value_size = bpf_map_value_size(map);
2056+
value_size = bpf_map_value_size(map, attr->batch.elem_flags);
20542057

20552058
max_count = attr->batch.count;
20562059
if (!max_count)
@@ -2172,7 +2175,7 @@ static int map_lookup_and_delete_elem(union bpf_attr *attr)
21722175
goto err_put;
21732176
}
21742177

2175-
value_size = bpf_map_value_size(map);
2178+
value_size = bpf_map_value_size(map, 0);
21762179

21772180
err = -ENOMEM;
21782181
value = kvmalloc(value_size, GFP_USER | __GFP_NOWARN);

tools/include/uapi/linux/bpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,8 @@ enum {
13721372
BPF_NOEXIST = 1, /* create new element if it didn't exist */
13731373
BPF_EXIST = 2, /* update existing element */
13741374
BPF_F_LOCK = 4, /* spin_lock-ed map_lookup/map_update */
1375+
BPF_F_CPU = 8, /* cpu flag for percpu maps, upper 32-bit of flags is a cpu number */
1376+
BPF_F_ALL_CPUS = 16, /* update value across all CPUs for percpu maps */
13751377
};
13761378

13771379
/* flags for BPF_MAP_CREATE command */

0 commit comments

Comments
 (0)