perf arm-spe: Save clock parameters from TIME_CONV event
authorLeo Yan <leo.yan@linaro.org>
Wed, 19 May 2021 07:19:35 +0000 (15:19 +0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 1 Jul 2021 19:14:36 +0000 (16:14 -0300)
During the recording phase, "perf record" tool synthesizes event
PERF_RECORD_TIME_CONV for the hardware clock parameters and saves the
event into the data file.

Afterwards, when processing the data file, the event TIME_CONV will be
processed at the very early time and is stored into session context.

This patch extracts these parameters from the session context and saves
into the structure "spe->tc" with the type perf_tsc_conversion, so that
the parameters are ready for conversion between clock counter and time
stamp.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: James Clark <james.clark@arm.com>
Tested-by: James Clark <james.clark@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Link: https://lore.kernel.org/r/20210519071939.1598923-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/arm-spe.c

index 2539d4baec448be33a5dc425e6831964b127ae4a..d2ae5a5c13ee952510fdd90de80170e41def223f 100644 (file)
@@ -26,6 +26,7 @@
 #include "symbol.h"
 #include "thread.h"
 #include "thread-stack.h"
+#include "tsc.h"
 #include "tool.h"
 #include "util/synthetic-events.h"
 
@@ -45,6 +46,8 @@ struct arm_spe {
        struct machine                  *machine;
        u32                             pmu_type;
 
+       struct perf_tsc_conversion      tc;
+
        u8                              timeless_decoding;
        u8                              data_queued;
 
@@ -1006,6 +1009,7 @@ int arm_spe_process_auxtrace_info(union perf_event *event,
 {
        struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
        size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX;
+       struct perf_record_time_conv *tc = &session->time_conv;
        struct arm_spe *spe;
        int err;
 
@@ -1027,6 +1031,28 @@ int arm_spe_process_auxtrace_info(union perf_event *event,
        spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
 
        spe->timeless_decoding = arm_spe__is_timeless_decoding(spe);
+
+       /*
+        * The synthesized event PERF_RECORD_TIME_CONV has been handled ahead
+        * and the parameters for hardware clock are stored in the session
+        * context.  Passes these parameters to the struct perf_tsc_conversion
+        * in "spe->tc", which is used for later conversion between clock
+        * counter and timestamp.
+        *
+        * For backward compatibility, copies the fields starting from
+        * "time_cycles" only if they are contained in the event.
+        */
+       spe->tc.time_shift = tc->time_shift;
+       spe->tc.time_mult = tc->time_mult;
+       spe->tc.time_zero = tc->time_zero;
+
+       if (event_contains(*tc, time_cycles)) {
+               spe->tc.time_cycles = tc->time_cycles;
+               spe->tc.time_mask = tc->time_mask;
+               spe->tc.cap_user_time_zero = tc->cap_user_time_zero;
+               spe->tc.cap_user_time_short = tc->cap_user_time_short;
+       }
+
        spe->auxtrace.process_event = arm_spe_process_event;
        spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
        spe->auxtrace.flush_events = arm_spe_flush;