Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20250730234733.530041-2-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Daniel Borkmann and committed by
Alexei Starovoitov
fd1c98f0 12df58ad

+49 -35
+24 -12
include/linux/bpf.h
··· 260 260 void *owner; 261 261 } __attribute__((aligned(8))); 262 262 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 + 263 275 struct bpf_map { 264 276 const struct bpf_map_ops *ops; 265 277 struct bpf_map *inner_map_meta; ··· 304 292 struct rcu_head rcu; 305 293 }; 306 294 atomic64_t writecnt; 307 - /* 'Ownership' of program-containing map is claimed by the first program 308 - * that is going to use this map or by the first program which FD is 309 - * stored in the map to make sure that all callers and callees have the 310 - * same prog type, JITed flag and xdp_has_frags flag. 311 - */ 312 - struct { 313 - const struct btf_type *attach_func_proto; 314 - spinlock_t lock; 315 - enum bpf_prog_type type; 316 - bool jited; 317 - bool xdp_has_frags; 318 - } owner; 295 + spinlock_t owner_lock; 296 + struct bpf_map_owner *owner; 319 297 bool bypass_spec_v1; 320 298 bool frozen; /* write-once; write-protected by freeze_mutex */ 321 299 bool free_after_mult_rcu_gp; ··· 2109 2107 { 2110 2108 return (access_flags & (BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG)) != 2111 2109 (BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG); 2110 + } 2111 + 2112 + static inline struct bpf_map_owner *bpf_map_owner_alloc(struct bpf_map *map) 2113 + { 2114 + return kzalloc(sizeof(*map->owner), GFP_ATOMIC); 2115 + } 2116 + 2117 + static inline void bpf_map_owner_free(struct bpf_map *map) 2118 + { 2119 + kfree(map->owner); 2112 2120 } 2113 2121 2114 2122 struct bpf_event_entry {
+18 -17
kernel/bpf/core.c
··· 2377 2377 const struct bpf_prog *fp) 2378 2378 { 2379 2379 enum bpf_prog_type prog_type = resolve_prog_type(fp); 2380 - bool ret; 2381 2380 struct bpf_prog_aux *aux = fp->aux; 2381 + bool ret = false; 2382 2382 2383 2383 if (fp->kprobe_override) 2384 - return false; 2384 + return ret; 2385 2385 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; 2395 2396 ret = true; 2396 2397 } 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; 2400 2401 if (ret && 2401 - map->owner.attach_func_proto != aux->attach_func_proto) { 2402 + map->owner->attach_func_proto != aux->attach_func_proto) { 2402 2403 switch (prog_type) { 2403 2404 case BPF_PROG_TYPE_TRACING: 2404 2405 case BPF_PROG_TYPE_LSM: ··· 2412 2411 } 2413 2412 } 2414 2413 } 2415 - spin_unlock(&map->owner.lock); 2416 - 2414 + err: 2415 + spin_unlock(&map->owner_lock); 2417 2416 return ret; 2418 2417 } 2419 2418
+7 -6
kernel/bpf/syscall.c
··· 887 887 888 888 security_bpf_map_free(map); 889 889 bpf_map_release_memcg(map); 890 + bpf_map_owner_free(map); 890 891 bpf_map_free(map); 891 892 } 892 893 ··· 982 981 struct bpf_map *map = filp->private_data; 983 982 u32 type = 0, jited = 0; 984 983 985 - if (map_type_contains_progs(map)) { 986 - spin_lock(&map->owner.lock); 987 - type = map->owner.type; 988 - jited = map->owner.jited; 989 - spin_unlock(&map->owner.lock); 984 + spin_lock(&map->owner_lock); 985 + if (map->owner) { 986 + type = map->owner->type; 987 + jited = map->owner->jited; 990 988 } 989 + spin_unlock(&map->owner_lock); 991 990 992 991 seq_printf(m, 993 992 "map_type:\t%u\n" ··· 1497 1496 atomic64_set(&map->refcnt, 1); 1498 1497 atomic64_set(&map->usercnt, 1); 1499 1498 mutex_init(&map->freeze_mutex); 1500 - spin_lock_init(&map->owner.lock); 1499 + spin_lock_init(&map->owner_lock); 1501 1500 1502 1501 if (attr->btf_key_type_id || attr->btf_value_type_id || 1503 1502 /* Even the map's value is a kernel's struct,