summaryrefslogtreecommitdiffstats
path: root/kernel/events/core.c
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2024-02-06 21:05:45 -0800
committerIngo Molnar <mingo@kernel.org>2024-04-10 06:13:57 +0200
commitf38628b06c36222367e26820879789ae59e49f60 (patch)
tree3a2cea20a240a80f2d5bbf7df451221d05241a1f /kernel/events/core.c
parent0259bf63f71e2accfeca4a4e346ede8edcc86aab (diff)
downloadlinux-stable-f38628b06c36222367e26820879789ae59e49f60.tar.gz
linux-stable-f38628b06c36222367e26820879789ae59e49f60.tar.bz2
linux-stable-f38628b06c36222367e26820879789ae59e49f60.zip
perf/core: Reduce PMU access to adjust sample freq
In perf_adjust_freq_unthr_context(), it first starts the event and then stop unnecessarily to adjust the sampling frequency if the event is throttled. For a throttled non-frequency event, it doesn't have a freq so no need to adjust. Just starting the event would be ok. For a frequency event, whether it's throttled or not, it needs to stop before adjusting the frequency. That means it should not start the even if it was throttled. I tried to skip calling the stop callback, but it didn't work well since the event count might not be up to date. It should call the stop callback with PERF_EF_UPDATE anyway. However not calling start would prevent unnecessary MSR accesses (which can be costly) for already stopped events as stop state is saved in the hw config. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Kan Liang <kan.liang@linux.intel.com> Link: https://lore.kernel.org/r/20240207050545.2727923-2-namhyung@kernel.org
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r--kernel/events/core.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 9566cfb27355..fd94e45a9d86 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4146,7 +4146,8 @@ static void perf_adjust_freq_unthr_events(struct list_head *event_list)
if (hwc->interrupts == MAX_INTERRUPTS) {
hwc->interrupts = 0;
perf_log_throttle(event, 1);
- event->pmu->start(event, 0);
+ if (!event->attr.freq || !event->attr.sample_freq)
+ event->pmu->start(event, 0);
}
if (!event->attr.freq || !event->attr.sample_freq)