perf expr: Make the online topology accessible globally
authorIan Rogers <irogers@google.com>
Sun, 19 Feb 2023 09:28:04 +0000 (01:28 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Sun, 19 Feb 2023 11:03:12 +0000 (08:03 -0300)
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@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Link: https://lore.kernel.org/r/20230219092848.639226-8-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/expr.c
tools/perf/util/cputopo.c
tools/perf/util/cputopo.h
tools/perf/util/expr.c
tools/perf/util/smt.c
tools/perf/util/smt.h

index a9eb1ed..cbf0e0c 100644 (file)
@@ -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",
index e08797c..ca1d833 100644 (file)
@@ -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;
index 969e592..8d42f61 100644 (file)
@@ -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. */
index c1da20b..d46a187 100644 (file)
@@ -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;
        }
index 994e9e4..650e804 100644 (file)
@@ -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);
 }
index ae9095f..01441fd 100644 (file)
@@ -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 */