Linux Perf Users
 help / color / mirror / Atom feed
* [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