diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 090ac3be7ab7..bac97441074a 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -597,7 +597,6 @@ struct perf_event { /* The cumulative AND of all event_caps for events in this group. */ int group_caps; - unsigned int group_generation; struct perf_event *group_leader; struct pmu *pmu; void *pmu_private; diff --git a/kernel/events/core.c b/kernel/events/core.c index cb9b49a5d71c..5fc26042a906 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1848,7 +1848,6 @@ static void perf_group_attach(struct perf_event *event) list_add_tail(&event->sibling_list, &group_leader->sibling_list); group_leader->nr_siblings++; - group_leader->group_generation++; perf_event__header_size(group_leader); @@ -1919,7 +1918,6 @@ static void perf_group_detach(struct perf_event *event) if (event->group_leader != event) { list_del_init(&event->sibling_list); event->group_leader->nr_siblings--; - event->group_leader->group_generation++; goto out; } @@ -4738,7 +4736,7 @@ static int __perf_read_group_add(struct perf_event *leader, u64 read_format, u64 *values) { struct perf_event_context *ctx = leader->ctx; - struct perf_event *sub, *parent; + struct perf_event *sub; unsigned long flags; int n = 1; /* skip @nr */ int ret; @@ -4748,33 +4746,6 @@ static int __perf_read_group_add(struct perf_event *leader, return ret; raw_spin_lock_irqsave(&ctx->lock, flags); - /* - * Verify the grouping between the parent and child (inherited) - * events is still in tact. - * - * Specifically: - * - leader->ctx->lock pins leader->sibling_list - * - parent->child_mutex pins parent->child_list - * - parent->ctx->mutex pins parent->sibling_list - * - * Because parent->ctx != leader->ctx (and child_list nests inside - * ctx->mutex), group destruction is not atomic between children, also - * see perf_event_release_kernel(). Additionally, parent can grow the - * group. - * - * Therefore it is possible to have parent and child groups in a - * different configuration and summing over such a beast makes no sense - * what so ever. - * - * Reject this. - */ - parent = leader->parent; - if (parent && - (parent->group_generation != leader->group_generation || - parent->nr_siblings != leader->nr_siblings)) { - ret = -ECHILD; - goto unlock; - } /* * Since we co-schedule groups, {enabled,running} times of siblings @@ -4804,9 +4775,8 @@ static int __perf_read_group_add(struct perf_event *leader, values[n++] = primary_event_id(sub); } -unlock: raw_spin_unlock_irqrestore(&ctx->lock, flags); - return ret; + return 0; } static int perf_read_group(struct perf_event *event, @@ -4825,6 +4795,10 @@ static int perf_read_group(struct perf_event *event, values[0] = 1 + leader->nr_siblings; + /* + * By locking the child_mutex of the leader we effectively + * lock the child list of all siblings.. XXX explain how. + */ mutex_lock(&leader->child_mutex); ret = __perf_read_group_add(leader, read_format, values); @@ -11613,7 +11587,6 @@ static int inherit_group(struct perf_event *parent_event, if (IS_ERR(child_ctr)) return PTR_ERR(child_ctr); } - leader->group_generation = parent_event->group_generation; return 0; }