[PATCH v2 2/7] perf arm-spe: Store TSC parameters in auxtrace info

From: Leo Yan
Date: Sat Apr 03 2021 - 03:24:36 EST


The TSC parameters are used for conversion between arch timer counter
and kernel timestamp, this patch stores the parameters into the struct
perf_record_auxtrace_info, and it is saved in perf data file.

Signed-off-by: Leo Yan <leo.yan@xxxxxxxxxx>
---
tools/perf/arch/arm64/util/arm-spe.c | 23 +++++++++++++++++++++++
tools/perf/util/arm-spe.h | 6 ++++++
2 files changed, 29 insertions(+)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 414c8a5584b1..dd940cf16f49 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -15,7 +15,9 @@
#include "../../../util/event.h"
#include "../../../util/evsel.h"
#include "../../../util/evlist.h"
+#include "../../../util/mmap.h"
#include "../../../util/session.h"
+#include "../../../util/tsc.h"
#include <internal/lib.h> // page_size
#include "../../../util/pmu.h"
#include "../../../util/debug.h"
@@ -47,6 +49,9 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
struct arm_spe_recording *sper =
container_of(itr, struct arm_spe_recording, itr);
struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu;
+ struct perf_event_mmap_page *pc;
+ struct perf_tsc_conversion tc = { .time_mult = 0, };
+ int err;

if (priv_size != ARM_SPE_AUXTRACE_PRIV_SIZE)
return -EINVAL;
@@ -54,8 +59,26 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
if (!session->evlist->core.nr_mmaps)
return -EINVAL;

+ pc = session->evlist->mmap[0].core.base;
+ if (pc) {
+ err = perf_read_tsc_conversion(pc, &tc);
+ if (err) {
+ if (err != -EOPNOTSUPP)
+ return err;
+ }
+
+ if (!tc.time_mult)
+ ui__warning("Arm SPE: arch timer not available\n");
+ }
+
auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
auxtrace_info->priv[ARM_SPE_PMU_TYPE] = arm_spe_pmu->type;
+ auxtrace_info->priv[ARM_SPE_TIME_SHIFT] = tc.time_shift;
+ auxtrace_info->priv[ARM_SPE_TIME_MULT] = tc.time_mult;
+ auxtrace_info->priv[ARM_SPE_TIME_ZERO] = tc.time_zero;
+ auxtrace_info->priv[ARM_SPE_TIME_CYCLES] = tc.time_cycles;
+ auxtrace_info->priv[ARM_SPE_TIME_MASK] = tc.time_mask;
+ auxtrace_info->priv[ARM_SPE_CAP_USER_TIME_SHORT] = tc.cap_user_time_short;

return 0;
}
diff --git a/tools/perf/util/arm-spe.h b/tools/perf/util/arm-spe.h
index 105ce0ea0a01..5bf3e838d226 100644
--- a/tools/perf/util/arm-spe.h
+++ b/tools/perf/util/arm-spe.h
@@ -11,6 +11,12 @@

enum {
ARM_SPE_PMU_TYPE,
+ ARM_SPE_TIME_SHIFT,
+ ARM_SPE_TIME_MULT,
+ ARM_SPE_TIME_ZERO,
+ ARM_SPE_TIME_CYCLES,
+ ARM_SPE_TIME_MASK,
+ ARM_SPE_CAP_USER_TIME_SHORT,
ARM_SPE_AUXTRACE_PRIV_MAX,
};

--
2.25.1