BPF link for some program types is passed as a "context" which can be used by those BPF programs to look up additional information. E.g., for multi-kprobes and multi-uprobes, link is used to fetch BPF cookie values. Because of this runtime dependency, when bpf_link refcnt drops to zero there could still be active BPF programs running accessing link data. This patch adds generic support to defer bpf_link dealloc callback to after RCU GP, if requested. This is done by exposing two different deallocation callbacks, one synchronous and one deferred. If deferred one is provided, bpf_link_free() will schedule dealloc_deferred() callback to happen after RCU GP. BPF is using two flavors of RCU: "classic" non-sleepable one and RCU tasks trace one. The latter is used when sleepable BPF programs are used. bpf_link_free() accommodates that by checking underlying BPF program's sleepable flag, and goes either through normal RCU GP only for non-sleepable, or through RCU tasks trace GP *and* then normal RCU GP (taking into account rcu_trace_implies_rcu_gp() optimization), if BPF program is sleepable. We use this for multi-kprobe and multi-uprobe links, which dereference link during program run. We also preventively switch raw_tp link to use deferred dealloc callback, as upcoming changes in bpf-next tree expose raw_tp link data (specifically, cookie value) to BPF program at runtime as well.
Showing the changes to kernel/trace (1 of 3 files). Show all
Unified · Split
| @@ -2728,7 +2728,7 @@ static int bpf_kprobe_multi_link_fill_link_info(const struct bpf_link *link, · 2727 unmodified lines | ||
| 2728 | 2728 | |
| 2729 | 2729 | static const struct bpf_link_ops bpf_kprobe_multi_link_lops = { |
| 2730 | 2730 | .release = bpf_kprobe_multi_link_release, |
| 2731 | − .dealloc = bpf_kprobe_multi_link_dealloc, | |
| 2731 | + .dealloc_deferred = bpf_kprobe_multi_link_dealloc, | |
| 2732 | 2732 | .fill_link_info = bpf_kprobe_multi_link_fill_link_info, |
| 2733 | 2733 | }; |
| 2734 | 2734 | |
| @@ -3242,7 +3242,7 @@ static int bpf_uprobe_multi_link_fill_link_info(const struct bpf_link *link, · 507 unmodified lines | ||
| 3242 | 3242 | |
| 3243 | 3243 | static const struct bpf_link_ops bpf_uprobe_multi_link_lops = { |
| 3244 | 3244 | .release = bpf_uprobe_multi_link_release, |
| 3245 | − .dealloc = bpf_uprobe_multi_link_dealloc, | |
| 3245 | + .dealloc_deferred = bpf_uprobe_multi_link_dealloc, | |
| 3246 | 3246 | .fill_link_info = bpf_uprobe_multi_link_fill_link_info, |
| 3247 | 3247 | }; |
| 3248 | 3248 | |