From 4934e8f7a83e433cd9a7e9de915de0b1eb377b0f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 26 Oct 2023 10:18:26 +0000 Subject: [PATCH] Revert "perf: Disallow mis-matched inherited group reads" This reverts commit 7252c8b981853bb8930de44fab924f947362683f which is commit 32671e3799ca2e4590773fd0e63aaa4229e50c06 upstream. It breaks the android ABI and if this is needed in the future, can be brought back in an abi-safe way. Bug: 161946584 Change-Id: Ia00890aeeef6153c7f3462a2a2189149734ac28a Signed-off-by: Greg Kroah-Hartman --- include/linux/perf_event.h | 1 - kernel/events/core.c | 39 ++++++-------------------------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 584c1a5f4099..f07f70ebd353 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -608,7 +608,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 0eb807a71f93..89f489c1f6c4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1849,7 +1849,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); @@ -2005,7 +2004,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; } @@ -4859,7 +4857,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; @@ -4869,33 +4867,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 @@ -4925,9 +4896,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, @@ -4946,6 +4916,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); @@ -12050,7 +12024,6 @@ static int inherit_group(struct perf_event *parent_event, !perf_get_aux_event(child_ctr, leader)) return -EINVAL; } - leader->group_generation = parent_event->group_generation; return 0; }