From 22d163151df1c871ae10da4810e0598de9d8c050 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 5 Jun 2025 14:27:18 +0000 Subject: [PATCH] Revert "perf: Avoid the read if the count is already updated" This reverts commit e1c3bfe365f10c3c5cfa53e16ad60201879f74f4 which is commit 8ce939a0fa194939cc1f92dbd8bc1a7806e7d40a upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: I9c672a97df39e7381e10c7cf113a5a36f76c90e4 Signed-off-by: Greg Kroah-Hartman --- include/linux/perf_event.h | 8 +------- kernel/events/core.c | 33 +++++++++++++++++---------------- kernel/events/ring_buffer.c | 1 - 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index f9804f51f38a..6ef9152c8348 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -937,13 +937,7 @@ struct perf_output_handle { struct perf_buffer *rb; unsigned long wakeup; unsigned long size; - union { - u64 flags; /* perf_output*() */ - u64 aux_flags; /* perf_aux_output*() */ - struct { - u64 skip_read : 1; - }; - }; + u64 aux_flags; union { void *addr; unsigned long head; diff --git a/kernel/events/core.c b/kernel/events/core.c index 43792736d14d..1ab3eef5cc7d 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1180,12 +1180,6 @@ static void perf_event_ctx_deactivate(struct perf_event_context *ctx) list_del_init(&ctx->active_ctx_list); } -static inline void perf_pmu_read(struct perf_event *event) -{ - if (event->state == PERF_EVENT_STATE_ACTIVE) - event->pmu->read(event); -} - static void get_ctx(struct perf_event_context *ctx) { refcount_inc(&ctx->refcount); @@ -3395,7 +3389,8 @@ static void __perf_event_sync_stat(struct perf_event *event, * we know the event must be on the current CPU, therefore we * don't need to use it. */ - perf_pmu_read(event); + if (event->state == PERF_EVENT_STATE_ACTIVE) + event->pmu->read(event); perf_event_update_time(event); @@ -4449,8 +4444,15 @@ static void __perf_event_read(void *info) pmu->read(event); - for_each_sibling_event(sub, event) - perf_pmu_read(sub); + for_each_sibling_event(sub, event) { + if (sub->state == PERF_EVENT_STATE_ACTIVE) { + /* + * Use sibling's PMU rather than @event's since + * sibling could be on different (eg: software) PMU. + */ + sub->pmu->read(sub); + } + } data->ret = pmu->commit_txn(pmu); @@ -7050,8 +7052,9 @@ static void perf_output_read_group(struct perf_output_handle *handle, if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) values[n++] = running; - if ((leader != event) && !handle->skip_read) - perf_pmu_read(leader); + if ((leader != event) && + (leader->state == PERF_EVENT_STATE_ACTIVE)) + leader->pmu->read(leader); values[n++] = perf_event_count(leader); if (read_format & PERF_FORMAT_ID) @@ -7064,8 +7067,9 @@ static void perf_output_read_group(struct perf_output_handle *handle, for_each_sibling_event(sub, leader) { n = 0; - if ((sub != event) && !handle->skip_read) - perf_pmu_read(sub); + if ((sub != event) && + (sub->state == PERF_EVENT_STATE_ACTIVE)) + sub->pmu->read(sub); values[n++] = perf_event_count(sub); if (read_format & PERF_FORMAT_ID) @@ -7120,9 +7124,6 @@ void perf_output_sample(struct perf_output_handle *handle, { u64 sample_type = data->type; - if (data->sample_flags & PERF_SAMPLE_READ) - handle->skip_read = 1; - perf_output_put(handle, *header); if (sample_type & PERF_SAMPLE_IDENTIFIER) diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 37f7451010b7..b9c010a0e0fe 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -181,7 +181,6 @@ __perf_output_begin(struct perf_output_handle *handle, handle->rb = rb; handle->event = event; - handle->flags = 0; have_lost = local_read(&rb->lost); if (unlikely(have_lost)) {