lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250822082233.1850417-1-dapeng1.mi@linux.intel.com>
Date: Fri, 22 Aug 2025 16:22:33 +0800
From: Dapeng Mi <dapeng1.mi@...ux.intel.com>
To: Peter Zijlstra <peterz@...radead.org>,
	Ingo Molnar <mingo@...hat.com>,
	Arnaldo Carvalho de Melo <acme@...nel.org>,
	Namhyung Kim <namhyung@...nel.org>,
	Ian Rogers <irogers@...gle.com>,
	Adrian Hunter <adrian.hunter@...el.com>,
	Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
	Kan Liang <kan.liang@...ux.intel.com>
Cc: linux-perf-users@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Dapeng Mi <dapeng1.mi@...el.com>,
	Dapeng Mi <dapeng1.mi@...ux.intel.com>,
	Xudong Hao <xudong.hao@...el.com>
Subject: [PATCH] perf tools topdown: Fix incorrect topdown slots regroup

When running the command "perf stat -e "slots,slots" -C0 sleep 1", we
see below error.

perf stat -e "slots,slots" -C0 sleep 1
WARNING: events were regrouped to match PMUs
 Performance counter stats for 'CPU(s) 0':
     <not counted>      slots
   <not supported>      slots

     1.002265769 seconds time elapsed

The topdown slots events are not correctly counted. The root cause is
that perf tools incorrectly regroup these 2 slots events into a group.
If there are only topdown slots events but no topdown metrics events,
the regroup should not be done since topdown slots event can only be
programed on fixed counter 3 and multiple slots events can only be
multiplexed to run on fixed counter 3, but grouping them blocks
multiplexing.

So avoid to regroup topdown slots events if there is no topdown metrics
events.

With this change, above command can be run successfully.

perf stat -e "slots,slots" -C0 sleep 1
 Performance counter stats for 'CPU(s) 0':
       103,973,791      slots
       106,488,170      slots

       1.003517284 seconds time elapsed

Besides, run perf stats/record test on SPR and PTL, both passed.

Reported-by: Xudong Hao <xudong.hao@...el.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@...ux.intel.com>
---
 tools/perf/arch/x86/util/topdown.h |  2 --
 tools/perf/util/evsel.c            | 10 ++++++++++
 tools/perf/util/evsel.h            |  2 ++
 tools/perf/util/parse-events.c     | 11 +++++++++++
 4 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/tools/perf/arch/x86/util/topdown.h b/tools/perf/arch/x86/util/topdown.h
index 69035565e649..6a917b2066f7 100644
--- a/tools/perf/arch/x86/util/topdown.h
+++ b/tools/perf/arch/x86/util/topdown.h
@@ -8,8 +8,6 @@ struct evsel;
 struct list_head;
 
 bool topdown_sys_has_perf_metrics(void);
-bool arch_is_topdown_slots(const struct evsel *evsel);
-bool arch_is_topdown_metrics(const struct evsel *evsel);
 int topdown_insert_slots_event(struct list_head *list, int idx, struct evsel *metric_event);
 
 #endif
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index d264c143b592..6aaae1ac026e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -3965,6 +3965,16 @@ int evsel__source_count(const struct evsel *evsel)
 	return count;
 }
 
+bool __weak arch_is_topdown_slots(const struct evsel *evsel __maybe_unused)
+{
+	return false;
+}
+
+bool __weak arch_is_topdown_metrics(const struct evsel *evsel __maybe_unused)
+{
+	return false;
+}
+
 bool __weak arch_evsel__must_be_in_group(const struct evsel *evsel __maybe_unused)
 {
 	return false;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 5797a02e5d6a..33f8aab675a9 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -556,6 +556,8 @@ void evsel__set_leader(struct evsel *evsel, struct evsel *leader);
 int evsel__source_count(const struct evsel *evsel);
 void evsel__remove_from_group(struct evsel *evsel, struct evsel *leader);
 
+bool arch_is_topdown_slots(const struct evsel *evsel);
+bool arch_is_topdown_metrics(const struct evsel *evsel);
 bool arch_evsel__must_be_in_group(const struct evsel *evsel);
 
 bool evsel__set_needs_uniquify(struct evsel *counter, const struct perf_stat_config *config);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 8282ddf68b98..bd09fc47ea90 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2127,6 +2127,8 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list)
 	int ret;
 	struct evsel *force_grouped_leader = NULL;
 	bool last_event_was_forced_leader = false;
+	bool has_slots = false;
+	bool has_metrics = false;
 
 	/* On x86 topdown metrics events require a slots event. */
 	ret = arch_evlist__add_required_events(list);
@@ -2147,6 +2149,11 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list)
 		if (pos == pos_leader)
 			orig_num_leaders++;
 
+		if (!has_slots)
+			has_slots = arch_is_topdown_slots(pos);
+		if (!has_metrics)
+			has_metrics = arch_is_topdown_metrics(pos);
+
 		/*
 		 * Ensure indexes are sequential, in particular for multiple
 		 * event lists being merged. The indexes are used to detect when
@@ -2163,6 +2170,10 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list)
 			force_grouped_idx = pos_leader->core.idx;
 	}
 
+	/* Don't regroup if there are only topdown slots events. */
+	if (force_grouped_idx != -1 && has_slots && !has_metrics)
+		force_grouped_idx = -1;
+
 	/* Sort events. */
 	list_sort(&force_grouped_idx, list, evlist__cmp);
 

base-commit: 6235ce77749f45cac27f630337e2fdf04e8a6c73
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ