forked from luck/tmp_suning_uos_patched
perf inject: Fix ARM SPE handling
[ Upstream commit 9e1a8d9f683260d50e0a14176d3f7c46a93b2700 ] 'perf inject' is currently not working for Arm SPE. When you try to run 'perf inject' and 'perf report' with a perf.data file that contains SPE traces, the tool reports a "Bad address" error: # ./perf record -e arm_spe_0/ts_enable=1,store_filter=1,branch_filter=1,load_filter=1/ -a -- sleep 1 # ./perf inject -i perf.data -o perf.inject.data --itrace # ./perf report -i perf.inject.data --stdio 0x42c00 [0x8]: failed to process type: 9 [Bad address] Error: failed to process sample As far as I know, the issue was first spotted in [1], but 'perf inject' was not yet injecting the samples. This patch does something similar to what cs_etm does for injecting the samples [2], but for SPE. [1] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20210412091006.468557-1-leo.yan@linaro.org/#24117339 [2] https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/tree/tools/perf/util/cs-etm.c?h=perf/core&id=133fe2e617e48ca0948983329f43877064ffda3e#n1196 Reviewed-by: James Clark <james.clark@arm.com> Signed-off-by: German Gomez <german.gomez@arm.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: John Garry <john.garry@huawei.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211105104130.28186-2-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
2c15d2a6ba
commit
d9b72274f3
|
@ -48,6 +48,7 @@ struct arm_spe {
|
|||
u8 timeless_decoding;
|
||||
u8 data_queued;
|
||||
|
||||
u64 sample_type;
|
||||
u8 sample_flc;
|
||||
u8 sample_llc;
|
||||
u8 sample_tlb;
|
||||
|
@ -244,6 +245,12 @@ static void arm_spe_prep_sample(struct arm_spe *spe,
|
|||
event->sample.header.size = sizeof(struct perf_event_header);
|
||||
}
|
||||
|
||||
static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
|
||||
{
|
||||
event->header.size = perf_event__sample_event_size(sample, type, 0);
|
||||
return perf_event__synthesize_sample(event, type, 0, sample);
|
||||
}
|
||||
|
||||
static inline int
|
||||
arm_spe_deliver_synth_event(struct arm_spe *spe,
|
||||
struct arm_spe_queue *speq __maybe_unused,
|
||||
|
@ -252,6 +259,12 @@ arm_spe_deliver_synth_event(struct arm_spe *spe,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (spe->synth_opts.inject) {
|
||||
ret = arm_spe__inject_event(event, sample, spe->sample_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = perf_session__deliver_synth_event(spe->session, event, sample);
|
||||
if (ret)
|
||||
pr_err("ARM SPE: failed to deliver event, error %d\n", ret);
|
||||
|
@ -809,6 +822,8 @@ arm_spe_synth_events(struct arm_spe *spe, struct perf_session *session)
|
|||
else
|
||||
attr.sample_type |= PERF_SAMPLE_TIME;
|
||||
|
||||
spe->sample_type = attr.sample_type;
|
||||
|
||||
attr.exclude_user = evsel->core.attr.exclude_user;
|
||||
attr.exclude_kernel = evsel->core.attr.exclude_kernel;
|
||||
attr.exclude_hv = evsel->core.attr.exclude_hv;
|
||||
|
|
Loading…
Reference in New Issue
Block a user