]> git.baikalelectronics.ru Git - kernel.git/commit
perf/core: Fix cgroup event list management
authorNamhyung Kim <namhyung@kernel.org>
Mon, 24 Jan 2022 19:58:08 +0000 (11:58 -0800)
committerPeter Zijlstra <peterz@infradead.org>
Wed, 26 Jan 2022 14:06:06 +0000 (15:06 +0100)
commite86b94f833a0677c33174b9f3b564e9d5f487cac
tree9596dd1f3248f220d82f977c2161d3f3e90f2f3b
parentbd22a7aea81713755ffc85ec5a529d138b7b0486
perf/core: Fix cgroup event list management

The active cgroup events are managed in the per-cpu cgrp_cpuctx_list.
This list is only accessed from current cpu and not protected by any
locks.  But from the commit 6e79869420f7 ("perf: Rework
perf_event_exit_event()"), it's possible to access (actually modify)
the list from another cpu.

In the perf_remove_from_context(), it can remove an event from the
context without an IPI when the context is not active.  This is not
safe with cgroup events which can have some active events in the
context even if ctx->is_active is 0 at the moment.  The target cpu
might be in the middle of list iteration at the same time.

If the event is enabled when it's about to be closed, it might call
perf_cgroup_event_disable() and list_del() with the cgrp_cpuctx_list
on a different cpu.

This resulted in a crash due to an invalid list pointer access during
the cgroup list traversal on the cpu which the event belongs to.

Let's fallback to IPI to access the cgrp_cpuctx_list from that cpu.
Similarly, perf_install_in_context() should use IPI for the cgroup
events too.

Fixes: 6e79869420f7 ("perf: Rework perf_event_exit_event()")
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20220124195808.2252071-1-namhyung@kernel.org
kernel/events/core.c