[PATCH v1 07/51] perf expr: Make the online topology accessible globally

Ian Rogers irogers at google.com
Sun Feb 19 01:28:04 PST 2023


Knowing the topology of online CPUs is useful for more than just expr
literals. Move to a global function that caches the value. An
additional upside is that this may also avoid computing the CPU
topology in some situations.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/expr.c   |  7 ++-----
 tools/perf/util/cputopo.c | 14 ++++++++++++++
 tools/perf/util/cputopo.h |  5 +++++
 tools/perf/util/expr.c    | 16 ++++++----------
 tools/perf/util/smt.c     | 11 +++++------
 tools/perf/util/smt.h     | 12 ++++++------
 6 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index a9eb1ed6bd63..cbf0e0c74906 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -154,13 +154,10 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u
 
 	/* Only EVENT1 or EVENT2 need be measured depending on the value of smt_on. */
 	{
-		struct cpu_topology *topology = cpu_topology__new();
-		bool smton = smt_on(topology);
+		bool smton = smt_on();
 		bool corewide = core_wide(/*system_wide=*/false,
-					  /*user_requested_cpus=*/false,
-					  topology);
+					  /*user_requested_cpus=*/false);
 
-		cpu_topology__delete(topology);
 		expr__ctx_clear(ctx);
 		TEST_ASSERT_VAL("find ids",
 				expr__find_ids("EVENT1 if #smt_on else EVENT2",
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c
index e08797c3cdbc..ca1d833a0c26 100644
--- a/tools/perf/util/cputopo.c
+++ b/tools/perf/util/cputopo.c
@@ -238,6 +238,20 @@ static bool has_die_topology(void)
 	return true;
 }
 
+const struct cpu_topology *online_topology(void)
+{
+	static const struct cpu_topology *topology;
+
+	if (!topology) {
+		topology = cpu_topology__new();
+		if (!topology) {
+			pr_err("Error creating CPU topology");
+			abort();
+		}
+	}
+	return topology;
+}
+
 struct cpu_topology *cpu_topology__new(void)
 {
 	struct cpu_topology *tp = NULL;
diff --git a/tools/perf/util/cputopo.h b/tools/perf/util/cputopo.h
index 969e5920a00e..8d42f6102954 100644
--- a/tools/perf/util/cputopo.h
+++ b/tools/perf/util/cputopo.h
@@ -56,6 +56,11 @@ struct hybrid_topology {
 	struct hybrid_topology_node	nodes[];
 };
 
+/*
+ * The topology for online CPUs, lazily created.
+ */
+const struct cpu_topology *online_topology(void);
+
 struct cpu_topology *cpu_topology__new(void);
 void cpu_topology__delete(struct cpu_topology *tp);
 /* Determine from the core list whether SMT was enabled. */
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index c1da20b868db..d46a1878bc9e 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -402,7 +402,7 @@ double arch_get_tsc_freq(void)
 
 double expr__get_literal(const char *literal, const struct expr_scanner_ctx *ctx)
 {
-	static struct cpu_topology *topology;
+	const struct cpu_topology *topology;
 	double result = NAN;
 
 	if (!strcmp("#num_cpus", literal)) {
@@ -421,31 +421,27 @@ double expr__get_literal(const char *literal, const struct expr_scanner_ctx *ctx
 	 * these strings gives an indication of the number of packages, dies,
 	 * etc.
 	 */
-	if (!topology) {
-		topology = cpu_topology__new();
-		if (!topology) {
-			pr_err("Error creating CPU topology");
-			goto out;
-		}
-	}
 	if (!strcasecmp("#smt_on", literal)) {
-		result = smt_on(topology) ? 1.0 : 0.0;
+		result = smt_on() ? 1.0 : 0.0;
 		goto out;
 	}
 	if (!strcmp("#core_wide", literal)) {
-		result = core_wide(ctx->system_wide, ctx->user_requested_cpu_list, topology)
+		result = core_wide(ctx->system_wide, ctx->user_requested_cpu_list)
 			? 1.0 : 0.0;
 		goto out;
 	}
 	if (!strcmp("#num_packages", literal)) {
+		topology = online_topology();
 		result = topology->package_cpus_lists;
 		goto out;
 	}
 	if (!strcmp("#num_dies", literal)) {
+		topology = online_topology();
 		result = topology->die_cpus_lists;
 		goto out;
 	}
 	if (!strcmp("#num_cores", literal)) {
+		topology = online_topology();
 		result = topology->core_cpus_lists;
 		goto out;
 	}
diff --git a/tools/perf/util/smt.c b/tools/perf/util/smt.c
index 994e9e418227..650e804d0adc 100644
--- a/tools/perf/util/smt.c
+++ b/tools/perf/util/smt.c
@@ -4,7 +4,7 @@
 #include "cputopo.h"
 #include "smt.h"
 
-bool smt_on(const struct cpu_topology *topology)
+bool smt_on(void)
 {
 	static bool cached;
 	static bool cached_result;
@@ -16,22 +16,21 @@ bool smt_on(const struct cpu_topology *topology)
 	if (sysfs__read_int("devices/system/cpu/smt/active", &fs_value) >= 0)
 		cached_result = (fs_value == 1);
 	else
-		cached_result = cpu_topology__smt_on(topology);
+		cached_result = cpu_topology__smt_on(online_topology());
 
 	cached = true;
 	return cached_result;
 }
 
-bool core_wide(bool system_wide, const char *user_requested_cpu_list,
-	       const struct cpu_topology *topology)
+bool core_wide(bool system_wide, const char *user_requested_cpu_list)
 {
 	/* If not everything running on a core is being recorded then we can't use core_wide. */
 	if (!system_wide)
 		return false;
 
 	/* Cheap case that SMT is disabled and therefore we're inherently core_wide. */
-	if (!smt_on(topology))
+	if (!smt_on())
 		return true;
 
-	return cpu_topology__core_wide(topology, user_requested_cpu_list);
+	return cpu_topology__core_wide(online_topology(), user_requested_cpu_list);
 }
diff --git a/tools/perf/util/smt.h b/tools/perf/util/smt.h
index ae9095f2c38c..01441fd2c0a2 100644
--- a/tools/perf/util/smt.h
+++ b/tools/perf/util/smt.h
@@ -2,16 +2,16 @@
 #ifndef __SMT_H
 #define __SMT_H 1
 
-struct cpu_topology;
-
-/* Returns true if SMT (aka hyperthreading) is enabled. */
-bool smt_on(const struct cpu_topology *topology);
+/*
+ * Returns true if SMT (aka hyperthreading) is enabled. Determined via sysfs or
+ * the online topology.
+ */
+bool smt_on(void);
 
 /*
  * Returns true when system wide and all SMT threads for a core are in the
  * user_requested_cpus map.
  */
-bool core_wide(bool system_wide, const char *user_requested_cpu_list,
-	       const struct cpu_topology *topology);
+bool core_wide(bool system_wide, const char *user_requested_cpu_list);
 
 #endif /* __SMT_H */
-- 
2.39.2.637.g21b0678d19-goog




More information about the linux-arm-kernel mailing list