Revert "perf: Disallow mis-matched inherited group reads"

This reverts commit a714491fa9 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 <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2023-10-26 10:18:26 +00:00
parent 1427d077a0
commit 9c20bfd64d
2 changed files with 6 additions and 34 deletions

View file

@ -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;

View file

@ -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;
}