Skip to content

Commit 98c8edf

Browse files
bpf: Move bpf map owner out of common struct
JIRA: https://issues.redhat.com/browse/RHEL-78204 commit fd1c98f Author: Daniel Borkmann <[email protected]> Date: Thu Jul 31 01:47:31 2025 +0200 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]> Signed-off-by: Jerome Marchand <[email protected]>
1 parent a46107c commit 98c8edf

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
@@ -2382,28 +2382,29 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
23822382
const struct bpf_prog *fp)
23832383
{
23842384
enum bpf_prog_type prog_type = resolve_prog_type(fp);
2385-
bool ret;
23862385
struct bpf_prog_aux *aux = fp->aux;
2386+
bool ret = false;
23872387

23882388
if (fp->kprobe_override)
2389-
return false;
2389+
return ret;
23902390

2391-
spin_lock(&map->owner.lock);
2392-
if (!map->owner.type) {
2393-
/* There's no owner yet where we could check for
2394-
* compatibility.
2395-
*/
2396-
map->owner.type = prog_type;
2397-
map->owner.jited = fp->jited;
2398-
map->owner.xdp_has_frags = aux->xdp_has_frags;
2399-
map->owner.attach_func_proto = aux->attach_func_proto;
2391+
spin_lock(&map->owner_lock);
2392+
/* There's no owner yet where we could check for compatibility. */
2393+
if (!map->owner) {
2394+
map->owner = bpf_map_owner_alloc(map);
2395+
if (!map->owner)
2396+
goto err;
2397+
map->owner->type = prog_type;
2398+
map->owner->jited = fp->jited;
2399+
map->owner->xdp_has_frags = aux->xdp_has_frags;
2400+
map->owner->attach_func_proto = aux->attach_func_proto;
24002401
ret = true;
24012402
} else {
2402-
ret = map->owner.type == prog_type &&
2403-
map->owner.jited == fp->jited &&
2404-
map->owner.xdp_has_frags == aux->xdp_has_frags;
2403+
ret = map->owner->type == prog_type &&
2404+
map->owner->jited == fp->jited &&
2405+
map->owner->xdp_has_frags == aux->xdp_has_frags;
24052406
if (ret &&
2406-
map->owner.attach_func_proto != aux->attach_func_proto) {
2407+
map->owner->attach_func_proto != aux->attach_func_proto) {
24072408
switch (prog_type) {
24082409
case BPF_PROG_TYPE_TRACING:
24092410
case BPF_PROG_TYPE_LSM:
@@ -2416,8 +2417,8 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
24162417
}
24172418
}
24182419
}
2419-
spin_unlock(&map->owner.lock);
2420-
2420+
err:
2421+
spin_unlock(&map->owner_lock);
24212422
return ret;
24222423
}
24232424

kernel/bpf/syscall.c

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

905905
security_bpf_map_free(map);
906906
bpf_map_release_memcg(map);
907+
bpf_map_owner_free(map);
907908
bpf_map_free(map);
908909
}
909910

@@ -998,12 +999,12 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
998999
struct bpf_map *map = filp->private_data;
9991000
u32 type = 0, jited = 0;
10001001

1001-
if (map_type_contains_progs(map)) {
1002-
spin_lock(&map->owner.lock);
1003-
type = map->owner.type;
1004-
jited = map->owner.jited;
1005-
spin_unlock(&map->owner.lock);
1002+
spin_lock(&map->owner_lock);
1003+
if (map->owner) {
1004+
type = map->owner->type;
1005+
jited = map->owner->jited;
10061006
}
1007+
spin_unlock(&map->owner_lock);
10071008

10081009
seq_printf(m,
10091010
"map_type:\t%u\n"
@@ -1513,7 +1514,7 @@ static int map_create(union bpf_attr *attr, bool kernel)
15131514
atomic64_set(&map->refcnt, 1);
15141515
atomic64_set(&map->usercnt, 1);
15151516
mutex_init(&map->freeze_mutex);
1516-
spin_lock_init(&map->owner.lock);
1517+
spin_lock_init(&map->owner_lock);
15171518

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

0 commit comments

Comments
 (0)