* [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
@ 2026-08-21 1:42 Deepanshu Kartikey
2026-08-21 1:56 ` sashiko-bot
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Deepanshu Kartikey @ 2026-08-21 1:42 UTC (permalink / raw)
To: peterz, mingo, acme, namhyung, mark.rutland, alexander.shishkin,
jolsa, olsajiri, irogers, adrian.hunter, james.clark, kpsingh,
matt, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, emil, ihor.solodrai, rostedt, mhiramat,
mathieu.desnoyers
Cc: linux-perf-users, linux-kernel, bpf, linux-trace-kernel,
Deepanshu Kartikey
During fork(), perf_event_alloc() reads parent_event->prog locklessly
which can race with a concurrent bpf_perf_link_release() clearing and
freeing the prog via perf_event_detach_bpf_prog(). This can result in
a NULL pointer dereference or use-after-free in bpf_prog_inc().
Fix by holding bpf_event_mutex when inheriting the BPF program during
fork(). Make bpf_event_mutex non-static and declare it extern in
perf_event.h so it is accessible from kernel/events/core.c.
Fixes: 85192dbf4de0 ("bpf: Convert bpf_prog refcnt to atomic64_t")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
include/linux/perf_event.h | 2 ++
kernel/events/core.c | 8 +++++---
kernel/trace/bpf_trace.c | 2 +-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 48d851fbd8ea..5c6dabb6dccb 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -2136,4 +2136,6 @@ static inline void perf_lopwr_cb(bool mode)
}
#endif
+extern struct mutex bpf_event_mutex;
+
#endif /* _LINUX_PERF_EVENT_H */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index ba5bd6a78fe7..a89e33c47073 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -13433,12 +13433,15 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
overflow_handler = parent_event->overflow_handler;
context = parent_event->overflow_handler_context;
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_EVENT_TRACING)
- if (parent_event->prog) {
- struct bpf_prog *prog = parent_event->prog;
-
+ struct bpf_prog *prog;
+
+ mutex_lock(&bpf_event_mutex);
+ prog = parent_event->prog;
+ if (prog) {
bpf_prog_inc(prog);
event->prog = prog;
}
+ mutex_unlock(&bpf_event_mutex);
#endif
}
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 75495a5c3507..730fc22a9daa 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1944,7 +1944,7 @@ const struct bpf_verifier_ops perf_event_verifier_ops = {
const struct bpf_prog_ops perf_event_prog_ops = {
};
-static DEFINE_MUTEX(bpf_event_mutex);
+DEFINE_MUTEX(bpf_event_mutex);
#define BPF_TRACE_MAX_PROGS 64
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
2026-08-21 1:42 [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() Deepanshu Kartikey
@ 2026-08-21 1:56 ` sashiko-bot
2026-08-21 2:32 ` bot+bpf-ci
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-08-21 1:56 UTC (permalink / raw)
To: Deepanshu Kartikey; +Cc: bpf, linux-trace-kernel, linux-perf-users
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [High] The patch introduces a build failure/linker error on configurations where `CONFIG_BPF_EVENTS` is disabled.
- [High] Severe global lock contention and performance regression during `fork()` for all inherited perf events.
Pre-existing issues:
- [High] Memory and reference count leak of BPF programs and address filters in the `perf_event_alloc` error path.
- [High] The patch fails to fix the use-after-free race condition for non-tracing events, as they bypass `bpf_event_mutex`.
- [High] Tracepoint BPF programs are globally detached and disabled when any inherited child perf event is closed.
--
--- Patch [1]: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() ---
commit f1b901f0de2c25ddd86c536608909f0fd81cff45
Author: Deepanshu Kartikey <kartikey406@gmail.com>
perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
This patch attempts to fix a use-after-free and NULL pointer dereference in
perf_event_alloc() during fork(). It introduces bpf_event_mutex to
synchronize the inheritance of the BPF program with concurrent detach
operations.
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 2eee83cdb43de..e62c34f1f89c7 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -13463,12 +13463,15 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
> overflow_handler = parent_event->overflow_handler;
> context = parent_event->overflow_handler_context;
> #if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_EVENT_TRACING)
> - if (parent_event->prog) {
> - struct bpf_prog *prog = parent_event->prog;
>
> + struct bpf_prog *prog;
> +
> + mutex_lock(&bpf_event_mutex);
[Severity: High]
Does this introduce a linker error when CONFIG_BPF_EVENTS is disabled?
The bpf_event_mutex is defined in kernel/trace/bpf_trace.c, which is only
compiled when CONFIG_BPF_EVENTS is enabled. However, this code is guarded by
checking CONFIG_BPF_SYSCALL and CONFIG_EVENT_TRACING.
If a configuration has CONFIG_BPF_SYSCALL=y, CONFIG_EVENT_TRACING=y, and
CONFIG_PERF_EVENTS=y, but disables CONFIG_KPROBE_EVENTS and
CONFIG_UPROBE_EVENTS, CONFIG_BPF_EVENTS evaluates to n. Will this result
in an undefined reference to bpf_event_mutex?
[Severity: High]
Does unconditionally acquiring this global lock penalize the performance of
process creation when basic perf inherited tracing is active?
This acquires bpf_event_mutex across all CPUs during fork() for every
inherited event, even when parent_event->prog is NULL. Should there be a
lockless fast-path check, for example:
if (READ_ONCE(parent_event->prog))
before acquiring the mutex?
[Severity: High]
This is a pre-existing issue, but does this fail to prevent the race
condition for non-tracing events?
While bpf_event_mutex is held here in perf_event_alloc(), concurrent
detach operations for non-tracing events bypass this mutex entirely:
kernel/events/core.c:perf_event_free_bpf_handler() {
event->prog = NULL;
bpf_prog_put(prog);
}
Since perf_event_free_bpf_handler() operates locklessly, doesn't the
original use-after-free vulnerability remain unfixed for event types
like BPF_PROG_TYPE_PERF_EVENT?
> + prog = parent_event->prog;
> + if (prog) {
> bpf_prog_inc(prog);
[Severity: High]
This is a pre-existing issue, but does this leak the BPF program reference
and address filters if perf_event_alloc() fails later on?
If a failure occurs after this point, the error path uses the
__free(__free_event) cleanup mechanism:
kernel/events/core.c:__free_event() {
...
}
Unlike _free_event(), __free_event() omits the calls to
perf_event_free_bpf_prog(event) and perf_free_addr_filters(event).
Will this leave the reference incremented by bpf_prog_inc() unbalanced?
> event->prog = prog;
[Severity: High]
This is a pre-existing issue, but does sharing the parent's program pointer
here cause tracepoint BPF programs to be globally detached when a child
exits?
When an inherited child event is closed, it eventually calls:
kernel/trace/bpf_trace.c:perf_event_detach_bpf_prog() {
...
ret = bpf_prog_array_copy(old_array, event->prog, NULL, 0, &new_array);
...
}
This permanently removes event->prog from the tracepoint's shared global
array. If an unprivileged child process exits, will it maliciously or
accidentally remove the parent's BPF program from the tracepoint entirely?
> }
> + mutex_unlock(&bpf_event_mutex);
> #endif
> }
[ ... ]
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 29260951aa871..73065ddad7f6d 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1944,7 +1944,7 @@ const struct bpf_verifier_ops perf_event_verifier_ops = {
> const struct bpf_prog_ops perf_event_prog_ops = {
> };
>
> -static DEFINE_MUTEX(bpf_event_mutex);
> +DEFINE_MUTEX(bpf_event_mutex);
>
> #define BPF_TRACE_MAX_PROGS 64
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260821014210.18681-1-kartikey406@gmail.com?part=1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
2026-08-21 1:42 [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() Deepanshu Kartikey
2026-08-21 1:56 ` sashiko-bot
@ 2026-08-21 2:32 ` bot+bpf-ci
2026-08-21 18:33 ` Andrii Nakryiko
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: bot+bpf-ci @ 2026-08-21 2:32 UTC (permalink / raw)
To: kartikey406, peterz, mingo, acme, namhyung, mark.rutland,
alexander.shishkin, jolsa, olsajiri, irogers, adrian.hunter,
james.clark, kpsingh, matt, ast, daniel, andrii, eddyz87, memxor,
martin.lau, song, yonghong.song, emil, ihor.solodrai, rostedt,
mhiramat, mathieu.desnoyers
Cc: linux-perf-users, linux-kernel, bpf, linux-trace-kernel,
kartikey406, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1757 bytes --]
> commit ba658ac0ee57b66edf6626745df8d57173c68285
> Author: Deepanshu Kartikey <kartikey406@gmail.com>
> Date: Fri Aug 21 07:12:10 2026 +0530
>
> perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
>
> During fork(), perf_event_alloc() reads parent_event->prog locklessly
> which can race with a concurrent bpf_perf_link_release() clearing and
> freeing the prog via perf_event_detach_bpf_prog(). This can result in
> a NULL pointer dereference or use-after-free in bpf_prog_inc().
>
> Fix by holding bpf_event_mutex when inheriting the BPF program during
> fork(). Make bpf_event_mutex non-static and declare it extern in
> perf_event.h so it is accessible from kernel/events/core.c.
>
> Fixes: 85192dbf4de0 ("bpf: Convert bpf_prog refcnt to atomic64_t")
The Fixes tag points at commit 85192dbf4de0 ("bpf: Convert bpf_prog
refcnt to atomic64_t") by Andrii Nakryiko, which only converted
bpf_prog->aux->refcnt from atomic_t to atomic64_t and made bpf_prog_inc()
non-failing.
That commit's modified-symbol set is entirely in kernel/bpf/,
include/linux/bpf.h and various net drivers, and it does not touch
kernel/events/core.c or perf_event_alloc() at all.
The unlocked read of parent_event->prog in perf_event_alloc() predates
it and was introduced by the commit that added BPF overflow-handler
inheritance to perf_event_alloc().
Should the Fixes tag name the commit that introduced the unlocked read so
the fix is backported to the right stable trees?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/32437947108
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
2026-08-21 1:42 [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() Deepanshu Kartikey
2026-08-21 1:56 ` sashiko-bot
2026-08-21 2:32 ` bot+bpf-ci
@ 2026-08-21 18:33 ` Andrii Nakryiko
2026-08-24 22:52 ` kernel test robot
2026-08-24 23:58 ` kernel test robot
4 siblings, 0 replies; 6+ messages in thread
From: Andrii Nakryiko @ 2026-08-21 18:33 UTC (permalink / raw)
To: Deepanshu Kartikey
Cc: peterz, mingo, acme, namhyung, mark.rutland, alexander.shishkin,
jolsa, olsajiri, irogers, adrian.hunter, james.clark, kpsingh,
matt, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, emil, ihor.solodrai, rostedt, mhiramat,
mathieu.desnoyers, linux-perf-users, linux-kernel, bpf,
linux-trace-kernel
On Thu, Aug 20, 2026 at 6:42 PM Deepanshu Kartikey
<kartikey406@gmail.com> wrote:
>
> During fork(), perf_event_alloc() reads parent_event->prog locklessly
> which can race with a concurrent bpf_perf_link_release() clearing and
> freeing the prog via perf_event_detach_bpf_prog(). This can result in
> a NULL pointer dereference or use-after-free in bpf_prog_inc().
>
> Fix by holding bpf_event_mutex when inheriting the BPF program during
> fork(). Make bpf_event_mutex non-static and declare it extern in
> perf_event.h so it is accessible from kernel/events/core.c.
>
> Fixes: 85192dbf4de0 ("bpf: Convert bpf_prog refcnt to atomic64_t")
> Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
> ---
> include/linux/perf_event.h | 2 ++
> kernel/events/core.c | 8 +++++---
> kernel/trace/bpf_trace.c | 2 +-
> 3 files changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 48d851fbd8ea..5c6dabb6dccb 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -2136,4 +2136,6 @@ static inline void perf_lopwr_cb(bool mode)
> }
> #endif
>
> +extern struct mutex bpf_event_mutex;
> +
exposing this mutex like that is definitely a smell.
AI tells me that this perf event inheritance case can happen for
non-tracing (i.e., BPF_PROG_TYPE_PERF_EVENT) events, which are
attached while holding perf_event_ctx_lock, not the bpf_event_mutex
(this one is held for tracepoint/kprobe/uprobe programs).
Please validate and adjust the fix.
> #endif /* _LINUX_PERF_EVENT_H */
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index ba5bd6a78fe7..a89e33c47073 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -13433,12 +13433,15 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
> overflow_handler = parent_event->overflow_handler;
> context = parent_event->overflow_handler_context;
> #if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_EVENT_TRACING)
> - if (parent_event->prog) {
> - struct bpf_prog *prog = parent_event->prog;
> -
> + struct bpf_prog *prog;
> +
> + mutex_lock(&bpf_event_mutex);
> + prog = parent_event->prog;
> + if (prog) {
> bpf_prog_inc(prog);
> event->prog = prog;
> }
> + mutex_unlock(&bpf_event_mutex);
> #endif
> }
>
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 75495a5c3507..730fc22a9daa 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1944,7 +1944,7 @@ const struct bpf_verifier_ops perf_event_verifier_ops = {
> const struct bpf_prog_ops perf_event_prog_ops = {
> };
>
> -static DEFINE_MUTEX(bpf_event_mutex);
> +DEFINE_MUTEX(bpf_event_mutex);
>
> #define BPF_TRACE_MAX_PROGS 64
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
2026-08-21 1:42 [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() Deepanshu Kartikey
` (2 preceding siblings ...)
2026-08-21 18:33 ` Andrii Nakryiko
@ 2026-08-24 22:52 ` kernel test robot
2026-08-24 23:58 ` kernel test robot
4 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-08-24 22:52 UTC (permalink / raw)
To: Deepanshu Kartikey, peterz, mingo, acme, namhyung, mark.rutland,
alexander.shishkin, jolsa, olsajiri, irogers, adrian.hunter,
james.clark, kpsingh, matt, ast, daniel, andrii, eddyz87, memxor,
martin.lau, song, yonghong.song, emil, ihor.solodrai, rostedt,
mhiramat, mathieu.desnoyers
Cc: oe-kbuild-all, linux-perf-users, linux-kernel, bpf,
linux-trace-kernel
Hi Deepanshu,
kernel test robot noticed the following build errors:
[auto build test ERROR on perf-tools-next/perf-tools-next]
[also build test ERROR on tip/perf/core perf-tools/perf-tools linus/master v7.2 next-20260821]
[cannot apply to acme/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Deepanshu-Kartikey/perf-bpf-Fix-lockless-access-to-parent_event-prog-in-perf_event_alloc/20260821-071210
base: https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf-tools-next
patch link: https://lore.kernel.org/r/20260821014210.18681-1-kartikey406%40gmail.com
patch subject: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
config: sparc-randconfig-002-20260825 (https://download.01.org/0day-ci/archive/20260825/202608250601.kP2R1VQE-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260825/202608250601.kP2R1VQE-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608250601.kP2R1VQE-lkp@intel.com/
All errors (new ones prefixed by >>):
sparc64-linux-ld: kernel/events/core.o: in function `perf_event_alloc':
>> kernel/events/core.c:13438:(.text+0x9be0): undefined reference to `bpf_event_mutex'
>> sparc64-linux-ld: kernel/events/core.c:13438:(.text+0x9bec): undefined reference to `bpf_event_mutex'
sparc64-linux-ld: kernel/events/core.c:13444:(.text+0x9c14): undefined reference to `bpf_event_mutex'
vim +13438 kernel/events/core.c
13340
13341 /*
13342 * Allocate and initialize an event structure
13343 */
13344 static struct perf_event *
13345 perf_event_alloc(struct perf_event_attr *attr, int cpu,
13346 struct task_struct *task,
13347 struct perf_event *group_leader,
13348 struct perf_event *parent_event,
13349 perf_overflow_handler_t overflow_handler,
13350 void *context, int cgroup_fd)
13351 {
13352 struct pmu *pmu;
13353 struct hw_perf_event *hwc;
13354 long err = -EINVAL;
13355 int node;
13356
13357 if ((unsigned)cpu >= nr_cpu_ids) {
13358 if (!task || cpu != -1)
13359 return ERR_PTR(-EINVAL);
13360 }
13361 if (attr->sigtrap && !task) {
13362 /* Requires a task: avoid signalling random tasks. */
13363 return ERR_PTR(-EINVAL);
13364 }
13365
13366 node = (cpu >= 0) ? cpu_to_node(cpu) : -1;
13367 struct perf_event *event __free(__free_event) =
13368 kmem_cache_alloc_node(perf_event_cache, GFP_KERNEL | __GFP_ZERO, node);
13369 if (!event)
13370 return ERR_PTR(-ENOMEM);
13371
13372 /*
13373 * Single events are their own group leaders, with an
13374 * empty sibling list:
13375 */
13376 if (!group_leader)
13377 group_leader = event;
13378
13379 mutex_init(&event->child_mutex);
13380 INIT_LIST_HEAD(&event->child_list);
13381
13382 INIT_LIST_HEAD(&event->event_entry);
13383 INIT_LIST_HEAD(&event->sibling_list);
13384 INIT_LIST_HEAD(&event->active_list);
13385 init_event_group(event);
13386 INIT_LIST_HEAD(&event->rb_entry);
13387 INIT_LIST_HEAD(&event->active_entry);
13388 INIT_LIST_HEAD(&event->addr_filters.list);
13389 INIT_HLIST_NODE(&event->hlist_entry);
13390 INIT_LIST_HEAD(&event->pmu_list);
13391
13392
13393 init_waitqueue_head(&event->waitq);
13394 init_irq_work(&event->pending_irq, perf_pending_irq);
13395 event->pending_disable_irq = IRQ_WORK_INIT_HARD(perf_pending_disable);
13396 init_task_work(&event->pending_task, perf_pending_task);
13397
13398 mutex_init(&event->mmap_mutex);
13399 raw_spin_lock_init(&event->addr_filters.lock);
13400
13401 atomic_long_set(&event->refcount, 1);
13402 event->cpu = cpu;
13403 event->attr = *attr;
13404 event->group_leader = group_leader;
13405 event->pmu = NULL;
13406 event->oncpu = -1;
13407
13408 event->parent = parent_event;
13409
13410 event->ns = get_pid_ns(task_active_pid_ns(current));
13411 event->id = atomic64_inc_return(&perf_event_id);
13412
13413 event->state = PERF_EVENT_STATE_INACTIVE;
13414
13415 if (parent_event)
13416 event->event_caps = parent_event->event_caps;
13417
13418 if (task) {
13419 event->attach_state = PERF_ATTACH_TASK;
13420 /*
13421 * XXX pmu::event_init needs to know what task to account to
13422 * and we cannot use the ctx information because we need the
13423 * pmu before we get a ctx.
13424 */
13425 event->hw.target = get_task_struct(task);
13426 }
13427
13428 event->clock = &local_clock;
13429 if (parent_event)
13430 event->clock = parent_event->clock;
13431
13432 if (!overflow_handler && parent_event) {
13433 overflow_handler = parent_event->overflow_handler;
13434 context = parent_event->overflow_handler_context;
13435 #if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_EVENT_TRACING)
13436 struct bpf_prog *prog;
13437
13438 mutex_lock(&bpf_event_mutex);
13439 prog = parent_event->prog;
13440 if (prog) {
13441 bpf_prog_inc(prog);
13442 event->prog = prog;
13443 }
13444 mutex_unlock(&bpf_event_mutex);
13445 #endif
13446 }
13447
13448 if (overflow_handler) {
13449 event->overflow_handler = overflow_handler;
13450 event->overflow_handler_context = context;
13451 } else if (is_write_backward(event)){
13452 event->overflow_handler = perf_event_output_backward;
13453 event->overflow_handler_context = NULL;
13454 } else {
13455 event->overflow_handler = perf_event_output_forward;
13456 event->overflow_handler_context = NULL;
13457 }
13458
13459 perf_event__state_init(event);
13460
13461 pmu = NULL;
13462
13463 hwc = &event->hw;
13464 hwc->sample_period = attr->sample_period;
13465 if (is_event_in_freq_mode(event))
13466 hwc->sample_period = 1;
13467 hwc->last_period = hwc->sample_period;
13468
13469 local64_set(&hwc->period_left, hwc->sample_period);
13470
13471 /*
13472 * We do not support PERF_SAMPLE_READ on inherited events unless
13473 * PERF_SAMPLE_TID is also selected, which allows inherited events to
13474 * collect per-thread samples.
13475 * See perf_output_read().
13476 */
13477 if (has_inherit_and_sample_read(attr) && !(attr->sample_type & PERF_SAMPLE_TID))
13478 return ERR_PTR(-EINVAL);
13479
13480 if (!has_branch_stack(event))
13481 event->attr.branch_sample_type = 0;
13482
13483 pmu = perf_init_event(event);
13484 if (IS_ERR(pmu))
13485 return (void*)pmu;
13486
13487 /*
13488 * The PERF_ATTACH_TASK_DATA is set in the event_init()->hw_config().
13489 * The attach should be right after the perf_init_event().
13490 * Otherwise, the __free_event() would mistakenly detach the non-exist
13491 * perf_ctx_data because of the other errors between them.
13492 */
13493 if (event->attach_state & PERF_ATTACH_TASK_DATA) {
13494 err = attach_perf_ctx_data(event);
13495 if (err)
13496 return ERR_PTR(err);
13497 }
13498
13499 /*
13500 * Disallow uncore-task events. Similarly, disallow uncore-cgroup
13501 * events (they don't make sense as the cgroup will be different
13502 * on other CPUs in the uncore mask).
13503 */
13504 if (pmu->task_ctx_nr == perf_invalid_context && (task || cgroup_fd != -1))
13505 return ERR_PTR(-EINVAL);
13506
13507 if (event->attr.aux_output &&
13508 (!(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT) ||
13509 event->attr.aux_pause || event->attr.aux_resume))
13510 return ERR_PTR(-EOPNOTSUPP);
13511
13512 if (event->attr.aux_pause && event->attr.aux_resume)
13513 return ERR_PTR(-EINVAL);
13514
13515 if (event->attr.aux_start_paused) {
13516 if (!(pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE))
13517 return ERR_PTR(-EOPNOTSUPP);
13518 event->hw.aux_paused = 1;
13519 }
13520
13521 if (cgroup_fd != -1) {
13522 err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader);
13523 if (err)
13524 return ERR_PTR(err);
13525 }
13526
13527 err = exclusive_event_init(event);
13528 if (err)
13529 return ERR_PTR(err);
13530
13531 if (has_addr_filter(event)) {
13532 event->addr_filter_ranges = kcalloc(pmu->nr_addr_filters,
13533 sizeof(struct perf_addr_filter_range),
13534 GFP_KERNEL);
13535 if (!event->addr_filter_ranges)
13536 return ERR_PTR(-ENOMEM);
13537
13538 /*
13539 * Clone the parent's vma offsets: they are valid until exec()
13540 * even if the mm is not shared with the parent.
13541 */
13542 if (event->parent) {
13543 struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
13544
13545 raw_spin_lock_irq(&ifh->lock);
13546 memcpy(event->addr_filter_ranges,
13547 event->parent->addr_filter_ranges,
13548 pmu->nr_addr_filters * sizeof(struct perf_addr_filter_range));
13549 raw_spin_unlock_irq(&ifh->lock);
13550 }
13551
13552 /* force hw sync on the address filters */
13553 event->addr_filters_gen = 1;
13554 }
13555
13556 if (!event->parent) {
13557 if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
13558 err = get_callchain_buffers(attr->sample_max_stack);
13559 if (err)
13560 return ERR_PTR(err);
13561 event->attach_state |= PERF_ATTACH_CALLCHAIN;
13562 }
13563 }
13564
13565 err = security_perf_event_alloc(event);
13566 if (err)
13567 return ERR_PTR(err);
13568
13569 err = mediated_pmu_account_event(event);
13570 if (err)
13571 return ERR_PTR(err);
13572
13573 /* symmetric to unaccount_event() in _free_event() */
13574 account_event(event);
13575
13576 /*
13577 * Event creation should be under SRCU, see perf_pmu_unregister().
13578 */
13579 lockdep_assert_held(&pmus_srcu);
13580 scoped_guard (spinlock, &pmu->events_lock)
13581 list_add(&event->pmu_list, &pmu->events);
13582
13583 return_ptr(event);
13584 }
13585
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
2026-08-21 1:42 [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() Deepanshu Kartikey
` (3 preceding siblings ...)
2026-08-24 22:52 ` kernel test robot
@ 2026-08-24 23:58 ` kernel test robot
4 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-08-24 23:58 UTC (permalink / raw)
To: Deepanshu Kartikey, peterz, mingo, acme, namhyung, mark.rutland,
alexander.shishkin, jolsa, olsajiri, irogers, adrian.hunter,
james.clark, kpsingh, matt, ast, daniel, andrii, eddyz87, memxor,
martin.lau, song, yonghong.song, emil, ihor.solodrai, rostedt,
mhiramat, mathieu.desnoyers
Cc: oe-kbuild-all, linux-perf-users, linux-kernel, bpf,
linux-trace-kernel
Hi Deepanshu,
kernel test robot noticed the following build errors:
[auto build test ERROR on perf-tools-next/perf-tools-next]
[also build test ERROR on tip/perf/core perf-tools/perf-tools linus/master v7.2 next-20260821]
[cannot apply to acme/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Deepanshu-Kartikey/perf-bpf-Fix-lockless-access-to-parent_event-prog-in-perf_event_alloc/20260821-071210
base: https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf-tools-next
patch link: https://lore.kernel.org/r/20260821014210.18681-1-kartikey406%40gmail.com
patch subject: [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc()
config: arm-randconfig-004-20260825 (https://download.01.org/0day-ci/archive/20260825/202608250735.Idi1PQgE-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260825/202608250735.Idi1PQgE-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608250735.Idi1PQgE-lkp@intel.com/
All errors (new ones prefixed by >>):
arm-linux-gnueabi-ld: kernel/events/core.o: in function `__list_add':
>> include/linux/list.h:159:(.text.perf_event_alloc.part.0+0x96c): undefined reference to `bpf_event_mutex'
arm-linux-gnueabi-ld: drivers/pci/controller/cadence/pcie-cadence-plat.o: in function `cdns_plat_pcie_probe':
drivers/pci/controller/cadence/pcie-cadence-plat.c:85:(.text.cdns_plat_pcie_probe+0xfc): undefined reference to `cdns_pcie_host_setup'
vim +159 include/linux/list.h
d7c816733d501b5 Kees Cook 2016-08-17 147
^1da177e4c3f415 Linus Torvalds 2005-04-16 148 /*
^1da177e4c3f415 Linus Torvalds 2005-04-16 149 * Insert a new entry between two known consecutive entries.
^1da177e4c3f415 Linus Torvalds 2005-04-16 150 *
^1da177e4c3f415 Linus Torvalds 2005-04-16 151 * This is only for internal list manipulation where we know
^1da177e4c3f415 Linus Torvalds 2005-04-16 152 * the prev/next entries already!
^1da177e4c3f415 Linus Torvalds 2005-04-16 153 */
^1da177e4c3f415 Linus Torvalds 2005-04-16 154 static inline void __list_add(struct list_head *new,
^1da177e4c3f415 Linus Torvalds 2005-04-16 155 struct list_head *prev,
^1da177e4c3f415 Linus Torvalds 2005-04-16 156 struct list_head *next)
^1da177e4c3f415 Linus Torvalds 2005-04-16 157 {
d7c816733d501b5 Kees Cook 2016-08-17 158 if (!__list_add_valid(new, prev, next))
d7c816733d501b5 Kees Cook 2016-08-17 @159 return;
d7c816733d501b5 Kees Cook 2016-08-17 160
^1da177e4c3f415 Linus Torvalds 2005-04-16 161 next->prev = new;
^1da177e4c3f415 Linus Torvalds 2005-04-16 162 new->next = next;
^1da177e4c3f415 Linus Torvalds 2005-04-16 163 new->prev = prev;
1c97be677f72b3c Paul E. McKenney 2015-09-20 164 WRITE_ONCE(prev->next, new);
^1da177e4c3f415 Linus Torvalds 2005-04-16 165 }
^1da177e4c3f415 Linus Torvalds 2005-04-16 166
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-24 23:59 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-21 1:42 [PATCH] perf/bpf: Fix lockless access to parent_event->prog in perf_event_alloc() Deepanshu Kartikey
2026-08-21 1:56 ` sashiko-bot
2026-08-21 2:32 ` bot+bpf-ci
2026-08-21 18:33 ` Andrii Nakryiko
2026-08-24 22:52 ` kernel test robot
2026-08-24 23:58 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox