Skip to content

Commit 5f4e5ce

Browse files
liu-song-6Peter Zijlstra
authored andcommitted
perf: Fix list corruption in perf_cgroup_switch()
There's list corruption on cgrp_cpuctx_list. This happens on the following path: perf_cgroup_switch: list_for_each_entry(cgrp_cpuctx_list) cpu_ctx_sched_in ctx_sched_in ctx_pinned_sched_in merge_sched_in perf_cgroup_event_disable: remove the event from the list Use list_for_each_entry_safe() to allow removing an entry during iteration. Fixes: 058fe1c ("perf/core: Make cgroup switch visit only cpuctxs with cgroup events") Signed-off-by: Song Liu <[email protected]> Reviewed-by: Rik van Riel <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 1d90934 commit 5f4e5ce

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

kernel/events/core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list);
839839
*/
840840
static void perf_cgroup_switch(struct task_struct *task, int mode)
841841
{
842-
struct perf_cpu_context *cpuctx;
842+
struct perf_cpu_context *cpuctx, *tmp;
843843
struct list_head *list;
844844
unsigned long flags;
845845

@@ -850,7 +850,7 @@ static void perf_cgroup_switch(struct task_struct *task, int mode)
850850
local_irq_save(flags);
851851

852852
list = this_cpu_ptr(&cgrp_cpuctx_list);
853-
list_for_each_entry(cpuctx, list, cgrp_cpuctx_entry) {
853+
list_for_each_entry_safe(cpuctx, tmp, list, cgrp_cpuctx_entry) {
854854
WARN_ON_ONCE(cpuctx->ctx.nr_cgroups == 0);
855855

856856
perf_ctx_lock(cpuctx, cpuctx->task_ctx);

0 commit comments

Comments
 (0)