summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorKumar Kartikeya Dwivedi <memxor@gmail.com>2026-04-22 23:44:30 +0300
committerKumar Kartikeya Dwivedi <memxor@gmail.com>2026-04-22 23:44:31 +0300
commite85115ff37f20d5c64ffbfd911d67f3686e2472d (patch)
tree75cd91d5fedd4f282c409badce0bdc1bd5d3a823 /include/linux
parent9012cf2491e3c5d28d098b0d6da804af82977032 (diff)
parent8a20655749c625dcc4debdfdeeaa0cf8bb85c203 (diff)
downloadlinux-e85115ff37f20d5c64ffbfd911d67f3686e2472d.tar.xz
Merge branch 'bpf-add-support-for-sleepable-tracepoint-programs'
Mykyta Yatsenko says: ==================== bpf: Add support for sleepable tracepoint programs This series adds support for sleepable BPF programs attached to raw tracepoints (tp_btf, raw_tp) and classic tracepoints (tp). The motivation is to allow BPF programs on syscall tracepoints to use sleepable helpers such as bpf_copy_from_user(), enabling reliable user memory reads that can page-fault. This series removes restriction for faultable tracepoints: Patch 1 modifies __bpf_trace_run() to support sleepable programs. Patch 2 introduces bpf_prog_run_array_sleepable() to support new usecase. Patch 3 adds sleepable support for classic tracepoints (BPF_PROG_TYPE_TRACEPOINT) by introducing trace_call_bpf_faultable() and restructuring perf_syscall_enter/exit() to run BPF programs in faultable context. Patch 4 allows BPF_TRACE_RAW_TP, BPF_PROG_TYPE_RAW_TRACEPOINT, and BPF_PROG_TYPE_TRACEPOINT programs to be loaded as sleepable, with load-time and attach-time checks to reject sleepable programs on non-faultable tracepoints. Patch 5 adds libbpf SEC_DEF handlers: tp_btf.s, raw_tp.s, raw_tracepoint.s, tp.s, and tracepoint.s. Patch 6 adds selftests covering tp_btf.s, raw_tp.s, and tp.s positive cases using bpf_copy_from_user() plus negative tests for non-faultable tracepoints. Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> --- Changes in v13: - Invert if (prog->sleepable) check in bpf_prog_run_array_sleepable() - Link to v12: https://patch.msgid.link/20260422-sleepable_tracepoints-v12-0-744bf0e3b311@meta.com Changes in v12: - Style improvement in the bpf_prog_run_array_sleepable(): use guard(rcu)(), remove unnecessary defensive programming artifacts. - Link to v11: https://patch.msgid.link/20260421-sleepable_tracepoints-v11-0-d8ff138d6f05@meta.com Changes in v11: - Avoid running dummy prog in the bpf_prog_run_array_sleepable() - Migrate selftests from nanosleep() to getcwd() to avoid issues with the different struct layouts. - Link to v10: https://patch.msgid.link/20260415-sleepable_tracepoints-v10-0-161f40b33dd7@meta.com Changes in v10: - Guard per-prog recursion check in bpf_prog_run_array_sleepable() with prog->active NULL check, following the same pattern as commit 7dc211c1159d for prog->stats. dummy_bpf_prog has NULL active field and can appear in the array via bpf_prog_array_delete_safe() fallback on allocation failure. - Link to v9: https://patch.msgid.link/20260410-sleepable_tracepoints-v9-0-e719e664e84c@meta.com Changes in v9: - Fixed "classic raw tracepoints" to "raw tracepoints (tp_btf, raw_tp)" in commit message - Added bpf_prog_get_recursion_context() guard to __bpf_prog_test_run_raw_tp() to protect per-CPU private stack from concurrent sleepable test runs - Added new bpf_prog_run_array_sleepable() without is_uprobe parameter, remove all changes in bpf_prog_run_array_uprobe() - Refactored attach_tp() to use prefix array uniformly (matching attach_raw_tp() pattern), removing hardcoded strcmp() bare-name checks. - Recursion check in __bpf_prog_test_run_raw_tp() - Refactored selftests - Link to v8: https://patch.msgid.link/20260330-sleepable_tracepoints-v8-0-2e323467f3a0@meta.com Changes in v8: - Fix sleepable tracepoint support in bpf_prog_test_run() (Kumar, sashiko) - Link to v7: https://patch.msgid.link/20260325-sleepable_tracepoints-v6-0-2b182dacea13@meta.com Changes in v7: - Add recursion check (bpf_prog_get_recursion_context()) to make sure private stack is safe when sleepable program is preempted by itself (Alexei, Kumar) - Use combined rcu_read_lock_dont_migrate() instead of separate rcu_read_lock()/migrate_disable() calls for non-sleepable path (Alexei) - Link to v6: https://lore.kernel.org/bpf/20260324-sleepable_tracepoints-v6-0-81bab3a43f25@meta.com/ Changes in v6: - Remove recursion check from trace_call_bpf_faultable(), sleepable tracepoints are called from syscall enter/exit, no recursion is possible.(Kumar) - Refactor bpf_prog_run_array_uprobe() to support tracepoints usecase cleanly (Kumar) - Link to v5: https://lore.kernel.org/r/20260316-sleepable_tracepoints-v5-0-85525de71d25@meta.com Changes in v5: - Addressed AI review: zero initialize struct pt_regs in perf_call_bpf_enter(); changed handling tp.s and tracepoint.s in attach_tp() in libbpf. - Updated commit messages - Link to v4: https://lore.kernel.org/r/20260313-sleepable_tracepoints-v4-0-debc688a66b3@meta.com Changes in v4: - Follow uprobe_prog_run() pattern with explicit rcu_read_lock_trace() instead of relying on outer rcu_tasks_trace lock - Add sleepable support for classic raw tracepoints (raw_tp.s) - Add sleepable support for classic tracepoints (tp.s) with new trace_call_bpf_faultable() and restructured perf_syscall_enter/exit() - Add raw_tp.s, raw_tracepoint.s, tp.s, tracepoint.s SEC_DEF handlers - Replace growing type enumeration in error message with generic "program of this type cannot be sleepable" - Use PT_REGS_PARM1_SYSCALL (non-CO-RE) in BTF test - Add classic raw_tp and classic tracepoint sleepable tests - Link to v3: https://lore.kernel.org/r/20260311-sleepable_tracepoints-v3-0-3e9bbde5bd22@meta.com Changes in v3: - Moved faultable tracepoint check from attach time to load time in bpf_check_attach_target(), providing a clear verifier error message - Folded preempt_disable removal into the sleepable execution path patch - Used RUN_TESTS() with __failure/__msg for negative test case instead of explicit userspace program - Reduced series from 6 patches to 4 - Link to v2: https://lore.kernel.org/r/20260225-sleepable_tracepoints-v2-0-0330dafd650f@meta.com Changes in v2: - Address AI review points - modified the order of the patches - Link to v1: https://lore.kernel.org/bpf/20260218-sleepable_tracepoints-v1-0-ec2705497208@meta.com/ --- ==================== Link: https://patch.msgid.link/20260422-sleepable_tracepoints-v13-0-99005dff21ef@meta.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bpf.h50
-rw-r--r--include/linux/trace_events.h6
2 files changed, 56 insertions, 0 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 3cb6b9e70080..d3aea3931b85 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -3079,6 +3079,56 @@ void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr);
void bpf_dynptr_set_rdonly(struct bpf_dynptr_kern *ptr);
void bpf_prog_report_arena_violation(bool write, unsigned long addr, unsigned long fault_ip);
+static __always_inline u32
+bpf_prog_run_array_sleepable(const struct bpf_prog_array *array,
+ const void *ctx, bpf_prog_run_fn run_prog)
+{
+ const struct bpf_prog_array_item *item;
+ struct bpf_prog *prog;
+ struct bpf_run_ctx *old_run_ctx;
+ struct bpf_trace_run_ctx run_ctx;
+ u32 ret = 1;
+
+ if (unlikely(!array))
+ return ret;
+
+ migrate_disable();
+
+ run_ctx.is_uprobe = false;
+
+ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
+ item = &array->items[0];
+ while ((prog = READ_ONCE(item->prog))) {
+ /* Skip dummy_bpf_prog placeholder (len == 0) */
+ if (unlikely(!prog->len)) {
+ item++;
+ continue;
+ }
+
+ if (unlikely(!bpf_prog_get_recursion_context(prog))) {
+ bpf_prog_inc_misses_counter(prog);
+ bpf_prog_put_recursion_context(prog);
+ item++;
+ continue;
+ }
+
+ run_ctx.bpf_cookie = item->bpf_cookie;
+
+ if (!prog->sleepable) {
+ guard(rcu)();
+ ret &= run_prog(prog, ctx);
+ } else {
+ ret &= run_prog(prog, ctx);
+ }
+
+ bpf_prog_put_recursion_context(prog);
+ item++;
+ }
+ bpf_reset_run_ctx(old_run_ctx);
+ migrate_enable();
+ return ret;
+}
+
#else /* !CONFIG_BPF_SYSCALL */
static inline struct bpf_prog *bpf_prog_get(u32 ufd)
{
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 40a43a4c7caf..d49338c44014 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -770,6 +770,7 @@ trace_trigger_soft_disabled(struct trace_event_file *file)
#ifdef CONFIG_BPF_EVENTS
unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx);
+unsigned int trace_call_bpf_faultable(struct trace_event_call *call, void *ctx);
int perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog *prog, u64 bpf_cookie);
void perf_event_detach_bpf_prog(struct perf_event *event);
int perf_event_query_prog_array(struct perf_event *event, void __user *info);
@@ -792,6 +793,11 @@ static inline unsigned int trace_call_bpf(struct trace_event_call *call, void *c
return 1;
}
+static inline unsigned int trace_call_bpf_faultable(struct trace_event_call *call, void *ctx)
+{
+ return 1;
+}
+
static inline int
perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog *prog, u64 bpf_cookie)
{