Skip to content

Commit fd1c98f

Browse files
borkmannAlexei Starovoitov
authored andcommitted
bpf: Move bpf map owner out of common struct
Given this is only relevant for BPF tail call maps, it is adding up space and penalizing other map types. We also need to extend this with further objects to track / compare to. Therefore, lets move this out into a separate structure and dynamically allocate it only for BPF tail call maps. Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 12df58a commit fd1c98f

File tree

3 files changed

+49
-35
lines changed

3 files changed

+49
-35
lines changed

include/linux/bpf.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,18 @@ struct bpf_list_node_kern {
260260
void *owner;
261261
} __attribute__((aligned(8)));
262262

263+
/* 'Ownership' of program-containing map is claimed by the first program
264+
* that is going to use this map or by the first program which FD is
265+
* stored in the map to make sure that all callers and callees have the
266+
* same prog type, JITed flag and xdp_has_frags flag.
267+
*/
268+
struct bpf_map_owner {
269+
enum bpf_prog_type type;
270+
bool jited;
271+
bool xdp_has_frags;
272+
const struct btf_type *attach_func_proto;
273+
};
274+
263275
struct bpf_map {
264276
const struct bpf_map_ops *ops;
265277
struct bpf_map *inner_map_meta;
@@ -292,18 +304,8 @@ struct bpf_map {
292304
struct rcu_head rcu;
293305
};
294306
atomic64_t writecnt;
295-
/* 'Ownership' of program-containing map is claimed by the first program
296-
* that is going to use this map or by the first program which FD is
297-
* stored in the map to make sure that all callers and callees have the
298-
* same prog type, JITed flag and xdp_has_frags flag.
299-
*/
300-
struct {
301-
const struct btf_type *attach_func_proto;
302-
spinlock_t lock;
303-
enum bpf_prog_type type;
304-
bool jited;
305-
bool xdp_has_frags;
306-
} owner;
307+
spinlock_t owner_lock;
308+
struct bpf_map_owner *owner;
307309
bool bypass_spec_v1;
308310
bool frozen; /* write-once; write-protected by freeze_mutex */
309311
bool free_after_mult_rcu_gp;
@@ -2109,6 +2111,16 @@ static inline bool bpf_map_flags_access_ok(u32 access_flags)
21092111
(BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG);
21102112
}
21112113

2114+
static inline struct bpf_map_owner *bpf_map_owner_alloc(struct bpf_map *map)
2115+
{
2116+
return kzalloc(sizeof(*map->owner), GFP_ATOMIC);
2117+
}
2118+
2119+
static inline void bpf_map_owner_free(struct bpf_map *map)
2120+
{
2121+
kfree(map->owner);
2122+
}
2123+
21122124
struct bpf_event_entry {
21132125
struct perf_event *event;
21142126
struct file *perf_file;

kernel/bpf/core.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,28 +2377,29 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
23772377
const struct bpf_prog *fp)
23782378
{
23792379
enum bpf_prog_type prog_type = resolve_prog_type(fp);
2380-
bool ret;
23812380
struct bpf_prog_aux *aux = fp->aux;
2381+
bool ret = false;
23822382

23832383
if (fp->kprobe_override)
2384-
return false;
2384+
return ret;
23852385

2386-
spin_lock(&map->owner.lock);
2387-
if (!map->owner.type) {
2388-
/* There's no owner yet where we could check for
2389-
* compatibility.
2390-
*/
2391-
map->owner.type = prog_type;
2392-
map->owner.jited = fp->jited;
2393-
map->owner.xdp_has_frags = aux->xdp_has_frags;
2394-
map->owner.attach_func_proto = aux->attach_func_proto;
2386+
spin_lock(&map->owner_lock);
2387+
/* There's no owner yet where we could check for compatibility. */
2388+
if (!map->owner) {
2389+
map->owner = bpf_map_owner_alloc(map);
2390+
if (!map->owner)
2391+
goto err;
2392+
map->owner->type = prog_type;
2393+
map->owner->jited = fp->jited;
2394+
map->owner->xdp_has_frags = aux->xdp_has_frags;
2395+
map->owner->attach_func_proto = aux->attach_func_proto;
23952396
ret = true;
23962397
} else {
2397-
ret = map->owner.type == prog_type &&
2398-
map->owner.jited == fp->jited &&
2399-
map->owner.xdp_has_frags == aux->xdp_has_frags;
2398+
ret = map->owner->type == prog_type &&
2399+
map->owner->jited == fp->jited &&
2400+
map->owner->xdp_has_frags == aux->xdp_has_frags;
24002401
if (ret &&
2401-
map->owner.attach_func_proto != aux->attach_func_proto) {
2402+
map->owner->attach_func_proto != aux->attach_func_proto) {
24022403
switch (prog_type) {
24032404
case BPF_PROG_TYPE_TRACING:
24042405
case BPF_PROG_TYPE_LSM:
@@ -2411,8 +2412,8 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
24112412
}
24122413
}
24132414
}
2414-
spin_unlock(&map->owner.lock);
2415-
2415+
err:
2416+
spin_unlock(&map->owner_lock);
24162417
return ret;
24172418
}
24182419

kernel/bpf/syscall.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ static void bpf_map_free_deferred(struct work_struct *work)
887887

888888
security_bpf_map_free(map);
889889
bpf_map_release_memcg(map);
890+
bpf_map_owner_free(map);
890891
bpf_map_free(map);
891892
}
892893

@@ -981,12 +982,12 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
981982
struct bpf_map *map = filp->private_data;
982983
u32 type = 0, jited = 0;
983984

984-
if (map_type_contains_progs(map)) {
985-
spin_lock(&map->owner.lock);
986-
type = map->owner.type;
987-
jited = map->owner.jited;
988-
spin_unlock(&map->owner.lock);
985+
spin_lock(&map->owner_lock);
986+
if (map->owner) {
987+
type = map->owner->type;
988+
jited = map->owner->jited;
989989
}
990+
spin_unlock(&map->owner_lock);
990991

991992
seq_printf(m,
992993
"map_type:\t%u\n"
@@ -1496,7 +1497,7 @@ static int map_create(union bpf_attr *attr, bool kernel)
14961497
atomic64_set(&map->refcnt, 1);
14971498
atomic64_set(&map->usercnt, 1);
14981499
mutex_init(&map->freeze_mutex);
1499-
spin_lock_init(&map->owner.lock);
1500+
spin_lock_init(&map->owner_lock);
15001501

15011502
if (attr->btf_key_type_id || attr->btf_value_type_id ||
15021503
/* Even the map's value is a kernel's struct,

0 commit comments

Comments
 (0)