Commit e5fa5b41 authored by Mike Leach's avatar Mike Leach Committed by Arnaldo Carvalho de Melo
Browse files

perf cs-etm: Update record event to use new Trace ID protocol



Trace IDs are now dynamically allocated.

Previously used the static association algorithm that is no longer
used. The 'cpu * 2 + seed' was outdated and broken for systems with high
core counts (>46). as it did not scale and was broken for larger
core counts.

Trace ID will now be sent in PERF_RECORD_AUX_OUTPUT_HW_ID record.

Legacy ID algorithm renamed and retained for limited backward
compatibility use.

Reviewed-by: default avatarJames Clark <james.clark@arm.com>
Signed-off-by: default avatarMike Leach <mike.leach@linaro.org>
Acked-by: default avatarSuzuki Poulouse <suzuki.poulose@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Darren Hart <darren@os.amperecomputing.com>
Cc: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: coresight@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: https://lore.kernel.org/r/20230331055645.26918-2-mike.leach@linaro.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 09277295
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -10,11 +10,27 @@
#include <linux/bits.h>

#define CORESIGHT_ETM_PMU_NAME "cs_etm"
#define CORESIGHT_ETM_PMU_SEED  0x10

/*
 * The legacy Trace ID system based on fixed calculation from the cpu
 * number. This has been replaced by drivers using a dynamic allocation
 * system - but need to retain the legacy algorithm for backward comparibility
 * in certain situations:-
 * a) new perf running on older systems that generate the legacy mapping
 * b) older tools that may not update at the same time as the kernel.
 */
#define CORESIGHT_LEGACY_CPU_TRACE_ID(cpu)  (0x10 + (cpu * 2))

/* CoreSight trace ID is currently the bottom 7 bits of the value */
#define CORESIGHT_TRACE_ID_VAL_MASK	GENMASK(6, 0)

/*
 * perf record will set the legacy meta data values as unused initially.
 * This allows perf report to manage the decoders created when dynamic
 * allocation in operation.
 */
#define CORESIGHT_TRACE_ID_UNUSED_FLAG	BIT(31)

/*
 * Below are the definition of bit offsets for perf option, and works as
 * arbitrary values for all ETM versions.
@@ -39,15 +55,4 @@
#define ETM4_CFG_BIT_RETSTK	12
#define ETM4_CFG_BIT_VMID_OPT	15

static inline int coresight_get_trace_id(int cpu)
{
	/*
	 * A trace ID of value 0 is invalid, so let's start at some
	 * random value that fits in 7 bits and go from there.  Since
	 * the common convention is to have data trace IDs be I(N) + 1,
	 * set instruction trace IDs as a function of the CPU number.
	 */
	return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
}

#endif
+17 −10
Original line number Diff line number Diff line
@@ -437,13 +437,16 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
	evlist__to_front(evlist, cs_etm_evsel);

	/*
	 * In the case of per-cpu mmaps, we need the CPU on the
	 * AUX event.  We also need the contextID in order to be notified
	 * when a context switch happened.
	 * get the CPU on the sample - need it to associate trace ID in the
	 * AUX_OUTPUT_HW_ID event, and the AUX event for per-cpu mmaps.
	 */
	if (!perf_cpu_map__empty(cpus)) {
	evsel__set_sample_bit(cs_etm_evsel, CPU);

	/*
	 * Also the case of per-cpu mmaps, need the contextID in order to be notified
	 * when a context switch happened.
	 */
	if (!perf_cpu_map__empty(cpus)) {
		err = cs_etm_set_option(itr, cs_etm_evsel,
					BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_TS));
		if (err)
@@ -679,8 +682,10 @@ static void cs_etm_save_etmv4_header(__u64 data[], struct auxtrace_record *itr,

	/* Get trace configuration register */
	data[CS_ETMV4_TRCCONFIGR] = cs_etmv4_get_config(itr);
	/* Get traceID from the framework */
	data[CS_ETMV4_TRCTRACEIDR] = coresight_get_trace_id(cpu);
	/* traceID set to legacy version, in case new perf running on older system */
	data[CS_ETMV4_TRCTRACEIDR] =
		CORESIGHT_LEGACY_CPU_TRACE_ID(cpu) | CORESIGHT_TRACE_ID_UNUSED_FLAG;

	/* Get read-only information from sysFS */
	data[CS_ETMV4_TRCIDR0] = cs_etm_get_ro(cs_etm_pmu, cpu,
					       metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
@@ -711,8 +716,10 @@ static void cs_etm_save_ete_header(__u64 data[], struct auxtrace_record *itr, in

	/* Get trace configuration register */
	data[CS_ETE_TRCCONFIGR] = cs_etmv4_get_config(itr);
	/* Get traceID from the framework */
	data[CS_ETE_TRCTRACEIDR] = coresight_get_trace_id(cpu);
	/* traceID set to legacy version, in case new perf running on older system */
	data[CS_ETE_TRCTRACEIDR] =
		CORESIGHT_LEGACY_CPU_TRACE_ID(cpu) | CORESIGHT_TRACE_ID_UNUSED_FLAG;

	/* Get read-only information from sysFS */
	data[CS_ETE_TRCIDR0] = cs_etm_get_ro(cs_etm_pmu, cpu,
					     metadata_ete_ro[CS_ETE_TRCIDR0]);
@@ -768,9 +775,9 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
		magic = __perf_cs_etmv3_magic;
		/* Get configuration register */
		info->priv[*offset + CS_ETM_ETMCR] = cs_etm_get_config(itr);
		/* Get traceID from the framework */
		/* traceID set to legacy value in case new perf running on old system */
		info->priv[*offset + CS_ETM_ETMTRACEIDR] =
						coresight_get_trace_id(cpu);
			CORESIGHT_LEGACY_CPU_TRACE_ID(cpu) | CORESIGHT_TRACE_ID_UNUSED_FLAG;
		/* Get read-only information from sysFS */
		info->priv[*offset + CS_ETM_ETMCCER] =
			cs_etm_get_ro(cs_etm_pmu, cpu,