]>
Commit | Line | Data |
---|---|---|
72c1d0fc GKH |
1 | From e9c856cabefb71d47b2eeb197f72c9c88e9b45b0 Mon Sep 17 00:00:00 2001 |
2 | From: Andrii Nakryiko <andrii@kernel.org> | |
3 | Date: Wed, 27 Mar 2024 22:24:25 -0700 | |
4 | Subject: bpf: put uprobe link's path and task in release callback | |
5 | ||
6 | From: Andrii Nakryiko <andrii@kernel.org> | |
7 | ||
8 | commit e9c856cabefb71d47b2eeb197f72c9c88e9b45b0 upstream. | |
9 | ||
10 | There is no need to delay putting either path or task to deallocation | |
11 | step. It can be done right after bpf_uprobe_unregister. Between release | |
12 | and dealloc, there could be still some running BPF programs, but they | |
13 | don't access either task or path, only data in link->uprobes, so it is | |
14 | safe to do. | |
15 | ||
16 | On the other hand, doing path_put() in dealloc callback makes this | |
17 | dealloc sleepable because path_put() itself might sleep. Which is | |
18 | problematic due to the need to call uprobe's dealloc through call_rcu(), | |
19 | which is what is done in the next bug fix patch. So solve the problem by | |
20 | releasing these resources early. | |
21 | ||
22 | Signed-off-by: Andrii Nakryiko <andrii@kernel.org> | |
23 | Link: https://lore.kernel.org/r/20240328052426.3042617-1-andrii@kernel.org | |
24 | Signed-off-by: Alexei Starovoitov <ast@kernel.org> | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
26 | --- | |
27 | kernel/trace/bpf_trace.c | 6 +++--- | |
28 | 1 file changed, 3 insertions(+), 3 deletions(-) | |
29 | ||
30 | --- a/kernel/trace/bpf_trace.c | |
31 | +++ b/kernel/trace/bpf_trace.c | |
32 | @@ -3065,6 +3065,9 @@ static void bpf_uprobe_multi_link_releas | |
33 | ||
34 | umulti_link = container_of(link, struct bpf_uprobe_multi_link, link); | |
35 | bpf_uprobe_unregister(&umulti_link->path, umulti_link->uprobes, umulti_link->cnt); | |
36 | + if (umulti_link->task) | |
37 | + put_task_struct(umulti_link->task); | |
38 | + path_put(&umulti_link->path); | |
39 | } | |
40 | ||
41 | static void bpf_uprobe_multi_link_dealloc(struct bpf_link *link) | |
42 | @@ -3072,9 +3075,6 @@ static void bpf_uprobe_multi_link_deallo | |
43 | struct bpf_uprobe_multi_link *umulti_link; | |
44 | ||
45 | umulti_link = container_of(link, struct bpf_uprobe_multi_link, link); | |
46 | - if (umulti_link->task) | |
47 | - put_task_struct(umulti_link->task); | |
48 | - path_put(&umulti_link->path); | |
49 | kvfree(umulti_link->uprobes); | |
50 | kfree(umulti_link); | |
51 | } |