|
@@ -941,6 +941,7 @@ static void perf_group_attach(struct perf_event *event)
|
|
|
static void
|
|
|
list_del_event(struct perf_event *event, struct perf_event_context *ctx)
|
|
|
{
|
|
|
+ struct perf_cpu_context *cpuctx;
|
|
|
/*
|
|
|
* We can have double detach due to exit/hot-unplug + close.
|
|
|
*/
|
|
@@ -949,8 +950,17 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
|
|
|
|
|
|
event->attach_state &= ~PERF_ATTACH_CONTEXT;
|
|
|
|
|
|
- if (is_cgroup_event(event))
|
|
|
+ if (is_cgroup_event(event)) {
|
|
|
ctx->nr_cgroups--;
|
|
|
+ cpuctx = __get_cpu_context(ctx);
|
|
|
+ /*
|
|
|
+ * if there are no more cgroup events
|
|
|
+ * then cler cgrp to avoid stale pointer
|
|
|
+ * in update_cgrp_time_from_cpuctx()
|
|
|
+ */
|
|
|
+ if (!ctx->nr_cgroups)
|
|
|
+ cpuctx->cgrp = NULL;
|
|
|
+ }
|
|
|
|
|
|
ctx->nr_events--;
|
|
|
if (event->attr.inherit_stat)
|