]> www.infradead.org Git - linux.git/commitdiff
perf arm-spe: Calculate meta data size
authorLeo Yan <leo.yan@arm.com>
Thu, 3 Oct 2024 18:42:59 +0000 (19:42 +0100)
committerNamhyung Kim <namhyung@kernel.org>
Thu, 3 Oct 2024 22:23:20 +0000 (15:23 -0700)
The metadata is designed to contain a header and per CPU information.

The arm_spe_find_cpus() function is introduced to identify how many CPUs
support ARM SPE. Based on the CPU number, calculates the metadata size.

Signed-off-by: Leo Yan <leo.yan@arm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Cc: Will Deacon <will@kernel.org>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Besar Wicaksono <bwicaksono@nvidia.com>
Cc: John Garry <john.g.garry@oracle.com>
Link: https://lore.kernel.org/r/20241003184302.190806-3-leo.yan@arm.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/arch/arm64/util/arm-spe.c

index 93c25909207118a9a76978e7716d16bf90077abe..cc927d88a6157096dc11f1015b688c6dffabd7bc 100644 (file)
@@ -37,11 +37,44 @@ struct arm_spe_recording {
        bool                    *wrapped;
 };
 
+/*
+ * arm_spe_find_cpus() returns a new cpu map, and the caller should invoke
+ * perf_cpu_map__put() to release the map after use.
+ */
+static struct perf_cpu_map *arm_spe_find_cpus(struct evlist *evlist)
+{
+       struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
+       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
+       struct perf_cpu_map *intersect_cpus;
+
+       /* cpu map is not "any" CPU , we have specific CPUs to work with */
+       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
+               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
+               perf_cpu_map__put(online_cpus);
+       /* Event can be "any" CPU so count all CPUs. */
+       } else {
+               intersect_cpus = online_cpus;
+       }
+
+       return intersect_cpus;
+}
+
 static size_t
 arm_spe_info_priv_size(struct auxtrace_record *itr __maybe_unused,
-                      struct evlist *evlist __maybe_unused)
+                      struct evlist *evlist)
 {
-       return ARM_SPE_AUXTRACE_V1_PRIV_SIZE;
+       struct perf_cpu_map *cpu_map = arm_spe_find_cpus(evlist);
+       size_t size;
+
+       if (!cpu_map)
+               return 0;
+
+       size = ARM_SPE_AUXTRACE_PRIV_MAX +
+              ARM_SPE_CPU_PRIV_MAX * perf_cpu_map__nr(cpu_map);
+       size *= sizeof(u64);
+
+       perf_cpu_map__put(cpu_map);
+       return size;
 }
 
 static int arm_spe_info_fill(struct auxtrace_record *itr,
@@ -53,7 +86,7 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
                        container_of(itr, struct arm_spe_recording, itr);
        struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu;
 
-       if (priv_size != ARM_SPE_AUXTRACE_V1_PRIV_SIZE)
+       if (priv_size != arm_spe_info_priv_size(itr, session->evlist))
                return -EINVAL;
 
        if (!session->evlist->core.nr_mmaps)