From: Leo Yan leo.yan@linaro.org
[ Upstream commit 51ba539f5bdb5a8cc7b1dedd5e73ac54564a7602 ]
Except for memory load and store operations, ARM SPE records also can support other operation types, bug when set the data source field the current code assumes a record is a either load operation or store operation, this leads to wrongly synthesize memory samples.
This patch strictly checks the record operation type, it only sets data source only for the operation types ARM_SPE_LD and ARM_SPE_ST, otherwise, returns zero for data source. Therefore, we can synthesize memory samples only when data source is a non-zero value, the function arm_spe__is_memory_event() is useless and removed.
Fixes: e55ed3423c1bb29f ("perf arm-spe: Synthesize memory event") Reviewed-by: Ali Saidi alisaidi@amazon.com Reviewed-by: German Gomez german.gomez@arm.com Signed-off-by: Leo Yan leo.yan@linaro.org Tested-by: Ali Saidi alisaidi@amazon.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: alisaidi@amazon.com Cc: Andrew Kilroy andrew.kilroy@arm.com Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: James Clark james.clark@arm.com Cc: Jiri Olsa jolsa@kernel.org Cc: John Garry john.garry@huawei.com Cc: Kajol Jain kjain@linux.ibm.com Cc: Leo Yan leo.yan@linaro.org Cc: Li Huafei lihuafei1@huawei.com Cc: linux-arm-kernel@lists.infradead.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Nick Forrington nick.forrington@arm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Will Deacon will@kernel.org Link: http://lore.kernel.org/lkml/20220517020326.18580-5-alisaidi@amazon.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/arm-spe.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 1a80151baed9..d040406f3314 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -387,26 +387,16 @@ static int arm_spe__synth_instruction_sample(struct arm_spe_queue *speq, return arm_spe_deliver_synth_event(spe, speq, event, &sample); }
-#define SPE_MEM_TYPE (ARM_SPE_L1D_ACCESS | ARM_SPE_L1D_MISS | \ - ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS | \ - ARM_SPE_REMOTE_ACCESS) - -static bool arm_spe__is_memory_event(enum arm_spe_sample_type type) -{ - if (type & SPE_MEM_TYPE) - return true; - - return false; -} - static u64 arm_spe__synth_data_source(const struct arm_spe_record *record) { union perf_mem_data_src data_src = { 0 };
if (record->op == ARM_SPE_LD) data_src.mem_op = PERF_MEM_OP_LOAD; - else + else if (record->op == ARM_SPE_ST) data_src.mem_op = PERF_MEM_OP_STORE; + else + return 0;
if (record->type & (ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS)) { data_src.mem_lvl = PERF_MEM_LVL_L3; @@ -510,7 +500,11 @@ static int arm_spe_sample(struct arm_spe_queue *speq) return err; }
- if (spe->sample_memory && arm_spe__is_memory_event(record->type)) { + /* + * When data_src is zero it means the record is not a memory operation, + * skip to synthesize memory sample for this case. + */ + if (spe->sample_memory && data_src) { err = arm_spe__synth_mem_sample(speq, spe->memory_id, data_src); if (err) return err;