Skip to content

Commit f13441c

Browse files
borkmanngregkh
authored andcommitted
bpf: Move bpf map owner out of common struct
[ Upstream commit fd1c98f ] 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 <daniel@iogearbox.net> Link: https://lore.kernel.org/r/20250730234733.530041-2-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org> Stable-dep-of: abad3d0 ("bpf: Fix oob access in cgroup local storage") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 963e79f commit f13441c

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
@@ -256,6 +256,18 @@ struct bpf_list_node_kern {
256256
void *owner;
257257
} __attribute__((aligned(8)));
258258

259+
/* 'Ownership' of program-containing map is claimed by the first program
260+
* that is going to use this map or by the first program which FD is
261+
* stored in the map to make sure that all callers and callees have the
262+
* same prog type, JITed flag and xdp_has_frags flag.
263+
*/
264+
struct bpf_map_owner {
265+
enum bpf_prog_type type;
266+
bool jited;
267+
bool xdp_has_frags;
268+
const struct btf_type *attach_func_proto;
269+
};
270+
259271
struct bpf_map {
260272
const struct bpf_map_ops *ops;
261273
struct bpf_map *inner_map_meta;
@@ -288,18 +300,8 @@ struct bpf_map {
288300
struct rcu_head rcu;
289301
};
290302
atomic64_t writecnt;
291-
/* 'Ownership' of program-containing map is claimed by the first program
292-
* that is going to use this map or by the first program which FD is
293-
* stored in the map to make sure that all callers and callees have the
294-
* same prog type, JITed flag and xdp_has_frags flag.
295-
*/
296-
struct {
297-
const struct btf_type *attach_func_proto;
298-
spinlock_t lock;
299-
enum bpf_prog_type type;
300-
bool jited;
301-
bool xdp_has_frags;
302-
} owner;
303+
spinlock_t owner_lock;
304+
struct bpf_map_owner *owner;
303305
bool bypass_spec_v1;
304306
bool frozen; /* write-once; write-protected by freeze_mutex */
305307
bool free_after_mult_rcu_gp;
@@ -1981,6 +1983,16 @@ static inline bool bpf_map_flags_access_ok(u32 access_flags)
19811983
(BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG);
19821984
}
19831985

1986+
static inline struct bpf_map_owner *bpf_map_owner_alloc(struct bpf_map *map)
1987+
{
1988+
return kzalloc(sizeof(*map->owner), GFP_ATOMIC);
1989+
}
1990+
1991+
static inline void bpf_map_owner_free(struct bpf_map *map)
1992+
{
1993+
kfree(map->owner);
1994+
}
1995+
19841996
struct bpf_event_entry {
19851997
struct perf_event *event;
19861998
struct file *perf_file;

kernel/bpf/core.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,28 +2310,29 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
23102310
const struct bpf_prog *fp)
23112311
{
23122312
enum bpf_prog_type prog_type = resolve_prog_type(fp);
2313-
bool ret;
23142313
struct bpf_prog_aux *aux = fp->aux;
2314+
bool ret = false;
23152315

23162316
if (fp->kprobe_override)
2317-
return false;
2317+
return ret;
23182318

2319-
spin_lock(&map->owner.lock);
2320-
if (!map->owner.type) {
2321-
/* There's no owner yet where we could check for
2322-
* compatibility.
2323-
*/
2324-
map->owner.type = prog_type;
2325-
map->owner.jited = fp->jited;
2326-
map->owner.xdp_has_frags = aux->xdp_has_frags;
2327-
map->owner.attach_func_proto = aux->attach_func_proto;
2319+
spin_lock(&map->owner_lock);
2320+
/* There's no owner yet where we could check for compatibility. */
2321+
if (!map->owner) {
2322+
map->owner = bpf_map_owner_alloc(map);
2323+
if (!map->owner)
2324+
goto err;
2325+
map->owner->type = prog_type;
2326+
map->owner->jited = fp->jited;
2327+
map->owner->xdp_has_frags = aux->xdp_has_frags;
2328+
map->owner->attach_func_proto = aux->attach_func_proto;
23282329
ret = true;
23292330
} else {
2330-
ret = map->owner.type == prog_type &&
2331-
map->owner.jited == fp->jited &&
2332-
map->owner.xdp_has_frags == aux->xdp_has_frags;
2331+
ret = map->owner->type == prog_type &&
2332+
map->owner->jited == fp->jited &&
2333+
map->owner->xdp_has_frags == aux->xdp_has_frags;
23332334
if (ret &&
2334-
map->owner.attach_func_proto != aux->attach_func_proto) {
2335+
map->owner->attach_func_proto != aux->attach_func_proto) {
23352336
switch (prog_type) {
23362337
case BPF_PROG_TYPE_TRACING:
23372338
case BPF_PROG_TYPE_LSM:
@@ -2344,8 +2345,8 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
23442345
}
23452346
}
23462347
}
2347-
spin_unlock(&map->owner.lock);
2348-
2348+
err:
2349+
spin_unlock(&map->owner_lock);
23492350
return ret;
23502351
}
23512352

kernel/bpf/syscall.c

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

768768
security_bpf_map_free(map);
769769
bpf_map_release_memcg(map);
770+
bpf_map_owner_free(map);
770771
bpf_map_free(map);
771772
}
772773

@@ -861,12 +862,12 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
861862
struct bpf_map *map = filp->private_data;
862863
u32 type = 0, jited = 0;
863864

864-
if (map_type_contains_progs(map)) {
865-
spin_lock(&map->owner.lock);
866-
type = map->owner.type;
867-
jited = map->owner.jited;
868-
spin_unlock(&map->owner.lock);
865+
spin_lock(&map->owner_lock);
866+
if (map->owner) {
867+
type = map->owner->type;
868+
jited = map->owner->jited;
869869
}
870+
spin_unlock(&map->owner_lock);
870871

871872
seq_printf(m,
872873
"map_type:\t%u\n"
@@ -1369,7 +1370,7 @@ static int map_create(union bpf_attr *attr)
13691370
atomic64_set(&map->refcnt, 1);
13701371
atomic64_set(&map->usercnt, 1);
13711372
mutex_init(&map->freeze_mutex);
1372-
spin_lock_init(&map->owner.lock);
1373+
spin_lock_init(&map->owner_lock);
13731374

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

0 commit comments

Comments
 (0)