perf arm-spe: Save clock parameters from TIME_CONV event

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>
This commit is contained in:
Leo Yan 2021-05-19 15:19:35 +08:00 committed by Arnaldo Carvalho de Melo
parent 2f01c200d4
commit c210c30696

View File

@ -26,6 +26,7 @@
#include "symbol.h" #include "symbol.h"
#include "thread.h" #include "thread.h"
#include "thread-stack.h" #include "thread-stack.h"
#include "tsc.h"
#include "tool.h" #include "tool.h"
#include "util/synthetic-events.h" #include "util/synthetic-events.h"
@ -45,6 +46,8 @@ struct arm_spe {
struct machine *machine; struct machine *machine;
u32 pmu_type; u32 pmu_type;
struct perf_tsc_conversion tc;
u8 timeless_decoding; u8 timeless_decoding;
u8 data_queued; 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; struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX; size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX;
struct perf_record_time_conv *tc = &session->time_conv;
struct arm_spe *spe; struct arm_spe *spe;
int err; 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->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
spe->timeless_decoding = arm_spe__is_timeless_decoding(spe); 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_event = arm_spe_process_event;
spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event; spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
spe->auxtrace.flush_events = arm_spe_flush; spe->auxtrace.flush_events = arm_spe_flush;