Skip to content

Commit 3b7a34a

Browse files
LeviYeoReumPeter Zijlstra
authored andcommitted
perf: Fix dangling cgroup pointer in cpuctx
Commit a3c3c66("perf/core: Fix child_total_time_enabled accounting bug at task exit") moves the event->state update to before list_del_event(). This makes the event->state test in list_del_event() always false; never calling perf_cgroup_event_disable(). As a result, cpuctx->cgrp won't be cleared properly; causing havoc. Fixes: a3c3c66("perf/core: Fix child_total_time_enabled accounting bug at task exit") Signed-off-by: Yeoreum Yun <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: David Wang <[email protected]> Link: https://lore.kernel.org/all/aD2TspKH%[email protected]/
1 parent 61988e3 commit 3b7a34a

File tree

1 file changed

+6
-15
lines changed

1 file changed

+6
-15
lines changed

kernel/events/core.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,18 +2120,6 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
21202120
if (event->group_leader == event)
21212121
del_event_from_groups(event, ctx);
21222122

2123-
/*
2124-
* If event was in error state, then keep it
2125-
* that way, otherwise bogus counts will be
2126-
* returned on read(). The only way to get out
2127-
* of error state is by explicit re-enabling
2128-
* of the event
2129-
*/
2130-
if (event->state > PERF_EVENT_STATE_OFF) {
2131-
perf_cgroup_event_disable(event, ctx);
2132-
perf_event_set_state(event, PERF_EVENT_STATE_OFF);
2133-
}
2134-
21352123
ctx->generation++;
21362124
event->pmu_ctx->nr_events--;
21372125
}
@@ -2488,11 +2476,14 @@ __perf_remove_from_context(struct perf_event *event,
24882476
state = PERF_EVENT_STATE_EXIT;
24892477
if (flags & DETACH_REVOKE)
24902478
state = PERF_EVENT_STATE_REVOKED;
2491-
if (flags & DETACH_DEAD) {
2492-
event->pending_disable = 1;
2479+
if (flags & DETACH_DEAD)
24932480
state = PERF_EVENT_STATE_DEAD;
2494-
}
2481+
24952482
event_sched_out(event, ctx);
2483+
2484+
if (event->state > PERF_EVENT_STATE_OFF)
2485+
perf_cgroup_event_disable(event, ctx);
2486+
24962487
perf_event_set_state(event, min(event->state, state));
24972488

24982489
if (flags & DETACH_GROUP)

0 commit comments

Comments
 (0)