Skip to content

Commit 66c8473

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
bpf: move sleepable flag from bpf_prog_aux to bpf_prog
prog->aux->sleepable is checked very frequently as part of (some) BPF program run hot paths. So this extra aux indirection seems wasteful and on busy systems might cause unnecessary memory cache misses. Let's move sleepable flag into prog itself to eliminate unnecessary pointer dereference. Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Jiri Olsa <[email protected]> Message-ID: <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent d6170e4 commit 66c8473

File tree

9 files changed

+21
-21
lines changed

9 files changed

+21
-21
lines changed

include/linux/bpf.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,6 @@ struct bpf_prog_aux {
14551455
bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */
14561456
bool attach_tracing_prog; /* true if tracing another tracing program */
14571457
bool func_proto_unreliable;
1458-
bool sleepable;
14591458
bool tail_call_reachable;
14601459
bool xdp_has_frags;
14611460
bool exception_cb;
@@ -1541,7 +1540,8 @@ struct bpf_prog {
15411540
enforce_expected_attach_type:1, /* Enforce expected_attach_type checking at attach time */
15421541
call_get_stack:1, /* Do we call bpf_get_stack() or bpf_get_stackid() */
15431542
call_get_func_ip:1, /* Do we call get_func_ip() */
1544-
tstamp_type_access:1; /* Accessed __sk_buff->tstamp_type */
1543+
tstamp_type_access:1, /* Accessed __sk_buff->tstamp_type */
1544+
sleepable:1; /* BPF program is sleepable */
15451545
enum bpf_prog_type type; /* Type of BPF program */
15461546
enum bpf_attach_type expected_attach_type; /* For some prog types */
15471547
u32 len; /* Number of filter blocks */
@@ -2112,14 +2112,14 @@ bpf_prog_run_array_uprobe(const struct bpf_prog_array __rcu *array_rcu,
21122112
old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
21132113
item = &array->items[0];
21142114
while ((prog = READ_ONCE(item->prog))) {
2115-
if (!prog->aux->sleepable)
2115+
if (!prog->sleepable)
21162116
rcu_read_lock();
21172117

21182118
run_ctx.bpf_cookie = item->bpf_cookie;
21192119
ret &= run_prog(prog, ctx);
21202120
item++;
21212121

2122-
if (!prog->aux->sleepable)
2122+
if (!prog->sleepable)
21232123
rcu_read_unlock();
21242124
}
21252125
bpf_reset_run_ctx(old_run_ctx);

kernel/bpf/bpf_iter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ int bpf_iter_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
548548
return -ENOENT;
549549

550550
/* Only allow sleepable program for resched-able iterator */
551-
if (prog->aux->sleepable && !bpf_iter_target_support_resched(tinfo))
551+
if (prog->sleepable && !bpf_iter_target_support_resched(tinfo))
552552
return -EINVAL;
553553

554554
link = kzalloc(sizeof(*link), GFP_USER | __GFP_NOWARN);
@@ -697,7 +697,7 @@ int bpf_iter_run_prog(struct bpf_prog *prog, void *ctx)
697697
struct bpf_run_ctx run_ctx, *old_run_ctx;
698698
int ret;
699699

700-
if (prog->aux->sleepable) {
700+
if (prog->sleepable) {
701701
rcu_read_lock_trace();
702702
migrate_disable();
703703
might_fault();

kernel/bpf/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,7 @@ void __bpf_free_used_maps(struct bpf_prog_aux *aux,
27062706
bool sleepable;
27072707
u32 i;
27082708

2709-
sleepable = aux->sleepable;
2709+
sleepable = aux->prog->sleepable;
27102710
for (i = 0; i < len; i++) {
27112711
map = used_maps[i];
27122712
if (map->ops->map_poke_untrack)

kernel/bpf/syscall.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,7 +2248,7 @@ static void __bpf_prog_put_noref(struct bpf_prog *prog, bool deferred)
22482248
btf_put(prog->aux->attach_btf);
22492249

22502250
if (deferred) {
2251-
if (prog->aux->sleepable)
2251+
if (prog->sleepable)
22522252
call_rcu_tasks_trace(&prog->aux->rcu, __bpf_prog_put_rcu);
22532253
else
22542254
call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
@@ -2813,11 +2813,11 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
28132813
}
28142814

28152815
prog->expected_attach_type = attr->expected_attach_type;
2816+
prog->sleepable = !!(attr->prog_flags & BPF_F_SLEEPABLE);
28162817
prog->aux->attach_btf = attach_btf;
28172818
prog->aux->attach_btf_id = attr->attach_btf_id;
28182819
prog->aux->dst_prog = dst_prog;
28192820
prog->aux->dev_bound = !!attr->prog_ifindex;
2820-
prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
28212821
prog->aux->xdp_has_frags = attr->prog_flags & BPF_F_XDP_HAS_FRAGS;
28222822

28232823
/* move token into prog->aux, reuse taken refcnt */
@@ -5554,7 +5554,7 @@ static int bpf_prog_bind_map(union bpf_attr *attr)
55545554
/* The bpf program will not access the bpf map, but for the sake of
55555555
* simplicity, increase sleepable_refcnt for sleepable program as well.
55565556
*/
5557-
if (prog->aux->sleepable)
5557+
if (prog->sleepable)
55585558
atomic64_inc(&map->sleepable_refcnt);
55595559
memcpy(used_maps_new, used_maps_old,
55605560
sizeof(used_maps_old[0]) * prog->aux->used_map_cnt);

kernel/bpf/trampoline.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr)
10141014

10151015
bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog)
10161016
{
1017-
bool sleepable = prog->aux->sleepable;
1017+
bool sleepable = prog->sleepable;
10181018

10191019
if (bpf_prog_check_recur(prog))
10201020
return sleepable ? __bpf_prog_enter_sleepable_recur :
@@ -1029,7 +1029,7 @@ bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog)
10291029

10301030
bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog)
10311031
{
1032-
bool sleepable = prog->aux->sleepable;
1032+
bool sleepable = prog->sleepable;
10331033

10341034
if (bpf_prog_check_recur(prog))
10351035
return sleepable ? __bpf_prog_exit_sleepable_recur :

kernel/bpf/verifier.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5274,7 +5274,7 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
52745274

52755275
static bool in_sleepable(struct bpf_verifier_env *env)
52765276
{
5277-
return env->prog->aux->sleepable;
5277+
return env->prog->sleepable;
52785278
}
52795279

52805280
/* The non-sleepable programs and sleepable programs with explicit bpf_rcu_read_lock()
@@ -18137,7 +18137,7 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
1813718137
return -EINVAL;
1813818138
}
1813918139

18140-
if (prog->aux->sleepable)
18140+
if (prog->sleepable)
1814118141
switch (map->map_type) {
1814218142
case BPF_MAP_TYPE_HASH:
1814318143
case BPF_MAP_TYPE_LRU_HASH:
@@ -18325,7 +18325,7 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env)
1832518325
return -E2BIG;
1832618326
}
1832718327

18328-
if (env->prog->aux->sleepable)
18328+
if (env->prog->sleepable)
1832918329
atomic64_inc(&map->sleepable_refcnt);
1833018330
/* hold the map. If the program is rejected by verifier,
1833118331
* the map will be released by release_maps() or it
@@ -20938,7 +20938,7 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
2093820938
}
2093920939
}
2094020940

20941-
if (prog->aux->sleepable) {
20941+
if (prog->sleepable) {
2094220942
ret = -EINVAL;
2094320943
switch (prog->type) {
2094420944
case BPF_PROG_TYPE_TRACING:
@@ -21049,14 +21049,14 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
2104921049
u64 key;
2105021050

2105121051
if (prog->type == BPF_PROG_TYPE_SYSCALL) {
21052-
if (prog->aux->sleepable)
21052+
if (prog->sleepable)
2105321053
/* attach_btf_id checked to be zero already */
2105421054
return 0;
2105521055
verbose(env, "Syscall programs can only be sleepable\n");
2105621056
return -EINVAL;
2105721057
}
2105821058

21059-
if (prog->aux->sleepable && !can_be_sleepable(prog)) {
21059+
if (prog->sleepable && !can_be_sleepable(prog)) {
2106021060
verbose(env, "Only fentry/fexit/fmod_ret, lsm, iter, uprobe, and struct_ops programs can be sleepable\n");
2106121061
return -EINVAL;
2106221062
}

kernel/events/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10553,7 +10553,7 @@ int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog,
1055310553
(is_syscall_tp && prog->type != BPF_PROG_TYPE_TRACEPOINT))
1055410554
return -EINVAL;
1055510555

10556-
if (prog->type == BPF_PROG_TYPE_KPROBE && prog->aux->sleepable && !is_uprobe)
10556+
if (prog->type == BPF_PROG_TYPE_KPROBE && prog->sleepable && !is_uprobe)
1055710557
/* only uprobe programs are allowed to be sleepable */
1055810558
return -EINVAL;
1055910559

kernel/trace/bpf_trace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3256,7 +3256,7 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe,
32563256
.uprobe = uprobe,
32573257
};
32583258
struct bpf_prog *prog = link->link.prog;
3259-
bool sleepable = prog->aux->sleepable;
3259+
bool sleepable = prog->sleepable;
32603260
struct bpf_run_ctx *old_run_ctx;
32613261
int err = 0;
32623262

net/bpf/bpf_dummy_struct_ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static int bpf_dummy_ops_check_member(const struct btf_type *t,
174174
case offsetof(struct bpf_dummy_ops, test_sleepable):
175175
break;
176176
default:
177-
if (prog->aux->sleepable)
177+
if (prog->sleepable)
178178
return -EINVAL;
179179
}
180180

0 commit comments

Comments
 (0)