mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
perf arm-spe: Save per CPU information in metadata
Save the Arm SPE information on a per-CPU basis. This approach is easier in the decoding phase for retrieving metadata based on the CPU number of every Arm SPE record. 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-4-leo.yan@arm.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
parent
59715b1908
commit
703f344d0c
|
|
@ -26,6 +26,8 @@
|
|||
#include "../../../util/arm-spe.h"
|
||||
#include <tools/libc_compat.h> // reallocarray
|
||||
|
||||
#define ARM_SPE_CPU_MAGIC 0x1010101010101010ULL
|
||||
|
||||
#define KiB(x) ((x) * 1024)
|
||||
#define MiB(x) ((x) * 1024 * 1024)
|
||||
|
||||
|
|
@ -77,14 +79,70 @@ arm_spe_info_priv_size(struct auxtrace_record *itr __maybe_unused,
|
|||
return size;
|
||||
}
|
||||
|
||||
static int arm_spe_save_cpu_header(struct auxtrace_record *itr,
|
||||
struct perf_cpu cpu, __u64 data[])
|
||||
{
|
||||
struct arm_spe_recording *sper =
|
||||
container_of(itr, struct arm_spe_recording, itr);
|
||||
struct perf_pmu *pmu = NULL;
|
||||
struct perf_pmu tmp_pmu;
|
||||
char cpu_id_str[16];
|
||||
char *cpuid = NULL;
|
||||
u64 val;
|
||||
|
||||
snprintf(cpu_id_str, sizeof(cpu_id_str), "%d", cpu.cpu);
|
||||
tmp_pmu.cpus = perf_cpu_map__new(cpu_id_str);
|
||||
if (!tmp_pmu.cpus)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Read CPU MIDR */
|
||||
cpuid = perf_pmu__getcpuid(&tmp_pmu);
|
||||
|
||||
/* The CPU map will not be used anymore, release it */
|
||||
perf_cpu_map__put(tmp_pmu.cpus);
|
||||
|
||||
if (!cpuid)
|
||||
return -ENOMEM;
|
||||
val = strtol(cpuid, NULL, 16);
|
||||
|
||||
data[ARM_SPE_MAGIC] = ARM_SPE_CPU_MAGIC;
|
||||
data[ARM_SPE_CPU] = cpu.cpu;
|
||||
data[ARM_SPE_CPU_NR_PARAMS] = ARM_SPE_CPU_PRIV_MAX - ARM_SPE_CPU_MIDR;
|
||||
data[ARM_SPE_CPU_MIDR] = val;
|
||||
|
||||
/* Find the associate Arm SPE PMU for the CPU */
|
||||
if (perf_cpu_map__has(sper->arm_spe_pmu->cpus, cpu))
|
||||
pmu = sper->arm_spe_pmu;
|
||||
|
||||
if (!pmu) {
|
||||
/* No Arm SPE PMU is found */
|
||||
data[ARM_SPE_CPU_PMU_TYPE] = ULLONG_MAX;
|
||||
data[ARM_SPE_CAP_MIN_IVAL] = 0;
|
||||
} else {
|
||||
data[ARM_SPE_CPU_PMU_TYPE] = pmu->type;
|
||||
|
||||
if (perf_pmu__scan_file(pmu, "caps/min_interval", "%lu", &val) != 1)
|
||||
val = 0;
|
||||
data[ARM_SPE_CAP_MIN_IVAL] = val;
|
||||
}
|
||||
|
||||
free(cpuid);
|
||||
return ARM_SPE_CPU_PRIV_MAX;
|
||||
}
|
||||
|
||||
static int arm_spe_info_fill(struct auxtrace_record *itr,
|
||||
struct perf_session *session,
|
||||
struct perf_record_auxtrace_info *auxtrace_info,
|
||||
size_t priv_size)
|
||||
{
|
||||
int i, ret;
|
||||
size_t offset;
|
||||
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_cpu_map *cpu_map;
|
||||
struct perf_cpu cpu;
|
||||
__u64 *data;
|
||||
|
||||
if (priv_size != arm_spe_info_priv_size(itr, session->evlist))
|
||||
return -EINVAL;
|
||||
|
|
@ -92,10 +150,31 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
|
|||
if (!session->evlist->core.nr_mmaps)
|
||||
return -EINVAL;
|
||||
|
||||
auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
|
||||
auxtrace_info->priv[ARM_SPE_PMU_TYPE] = arm_spe_pmu->type;
|
||||
cpu_map = arm_spe_find_cpus(session->evlist);
|
||||
if (!cpu_map)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
|
||||
auxtrace_info->priv[ARM_SPE_HEADER_VERSION] = ARM_SPE_HEADER_CURRENT_VERSION;
|
||||
auxtrace_info->priv[ARM_SPE_HEADER_SIZE] =
|
||||
ARM_SPE_AUXTRACE_PRIV_MAX - ARM_SPE_HEADER_VERSION;
|
||||
auxtrace_info->priv[ARM_SPE_PMU_TYPE_V2] = arm_spe_pmu->type;
|
||||
auxtrace_info->priv[ARM_SPE_CPUS_NUM] = perf_cpu_map__nr(cpu_map);
|
||||
|
||||
offset = ARM_SPE_AUXTRACE_PRIV_MAX;
|
||||
perf_cpu_map__for_each_cpu(cpu, i, cpu_map) {
|
||||
assert(offset < priv_size);
|
||||
data = &auxtrace_info->priv[offset];
|
||||
ret = arm_spe_save_cpu_header(itr, cpu, data);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
offset += ret;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
perf_cpu_map__put(cpu_map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user