Skip to content

Commit dc92feb

Browse files
author
Alexei Starovoitov
committed
bpf: Don't check for recursion in bpf_wq_work.
__bpf_prog_enter_sleepable_recur does recursion check which is not applicable to wq callback. The callback function is part of bpf program and bpf prog might be running on the same cpu. So recursion check would incorrectly prevent callback from running. The code can call __bpf_prog_enter_sleepable(), but run_ctx would be fake, hence use explicit rcu_read_lock_trace(); migrate_disable(); to address this problem. Another reason to open code is __bpf_prog_enter* are not available in !JIT configs. Reported-by: kernel test robot <[email protected]> Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Fixes: eb48f6c ("bpf: wq: add bpf_wq_init") Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 6e10b63 commit dc92feb

File tree

1 file changed

+5
-13
lines changed

1 file changed

+5
-13
lines changed

kernel/bpf/helpers.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,9 +1178,7 @@ static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer)
11781178
static void bpf_wq_work(struct work_struct *work)
11791179
{
11801180
struct bpf_work *w = container_of(work, struct bpf_work, work);
1181-
struct bpf_tramp_run_ctx __maybe_unused run_ctx;
11821181
struct bpf_async_cb *cb = &w->cb;
1183-
struct bpf_prog *prog = cb->prog;
11841182
struct bpf_map *map = cb->map;
11851183
bpf_callback_t callback_fn;
11861184
void *value = cb->value;
@@ -1190,7 +1188,7 @@ static void bpf_wq_work(struct work_struct *work)
11901188
BTF_TYPE_EMIT(struct bpf_wq);
11911189

11921190
callback_fn = READ_ONCE(cb->callback_fn);
1193-
if (!callback_fn || !prog)
1191+
if (!callback_fn)
11941192
return;
11951193

11961194
if (map->map_type == BPF_MAP_TYPE_ARRAY) {
@@ -1203,19 +1201,13 @@ static void bpf_wq_work(struct work_struct *work)
12031201
key = value - round_up(map->key_size, 8);
12041202
}
12051203

1206-
run_ctx.bpf_cookie = 0;
1207-
1208-
if (!__bpf_prog_enter_sleepable_recur(prog, &run_ctx)) {
1209-
/* recursion detected */
1210-
__bpf_prog_exit_sleepable_recur(prog, 0, &run_ctx);
1211-
return;
1212-
}
1204+
rcu_read_lock_trace();
1205+
migrate_disable();
12131206

12141207
callback_fn((u64)(long)map, (u64)(long)key, (u64)(long)value, 0, 0);
1215-
/* The verifier checked that return value is zero. */
12161208

1217-
__bpf_prog_exit_sleepable_recur(prog, 0 /* bpf_prog_run does runtime stats */,
1218-
&run_ctx);
1209+
migrate_enable();
1210+
rcu_read_unlock_trace();
12191211
}
12201212

12211213
static void bpf_wq_delete_work(struct work_struct *work)

0 commit comments

Comments
 (0)