diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h index 3afa8703b21d..fbb57f805237 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h @@ -28,6 +28,8 @@ #define ARM_SPE_L2D_ACCESS BIT(EV_L2D_ACCESS) #define ARM_SPE_L2D_MISS BIT(EV_L2D_MISS) #define ARM_SPE_RECENTLY_FETCHED BIT(EV_RECENTLY_FETCHED) +#define ARM_SPE_DATA_SNOOPED BIT(EV_DATA_SNOOPED) +#define ARM_SPE_HITM BIT(EV_CACHE_DATA_MODIFIED) enum arm_spe_op_type { /* First level operation type */ diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 58f80b5c0ab9..08cb493c3265 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -894,9 +894,12 @@ static void arm_spe__synth_st_memory_level(const struct arm_spe_record *record, } } -static void arm_spe__synth_memory_level(const struct arm_spe_record *record, +static void arm_spe__synth_memory_level(struct arm_spe_queue *speq, + const struct arm_spe_record *record, union perf_mem_data_src *data_src) { + struct arm_spe *spe = speq->spe; + if (data_src->mem_op == PERF_MEM_OP_LOAD) arm_spe__synth_ld_memory_level(record, data_src); if (data_src->mem_op == PERF_MEM_OP_STORE) @@ -907,6 +910,25 @@ static void arm_spe__synth_memory_level(const struct arm_spe_record *record, data_src->mem_lvl_num = PERF_MEM_LVLNUM_NA; } + if (record->type & ARM_SPE_DATA_SNOOPED) { + if (record->type & ARM_SPE_HITM) + data_src->mem_snoop = PERF_MEM_SNOOP_HITM; + else + data_src->mem_snoop = PERF_MEM_SNOOP_HIT; + } else { + u64 *metadata = arm_spe__get_metadata_by_cpu(spe, speq->cpu); + + /* + * Set NA ("Not available") mode if no meta data or the + * SNOOPED event is not supported. + */ + if (!metadata || + !(metadata[ARM_SPE_CAP_EVENT_FILTER] & ARM_SPE_DATA_SNOOPED)) + data_src->mem_snoop = PERF_MEM_SNOOP_NA; + else + data_src->mem_snoop = PERF_MEM_SNOOP_NONE; + } + if (record->type & ARM_SPE_REMOTE_ACCESS) data_src->mem_remote = PERF_MEM_REMOTE_REMOTE; } @@ -963,7 +985,7 @@ arm_spe__synth_data_source(struct arm_spe_queue *speq, return data_src; if (!arm_spe__synth_ds(speq, record, &data_src)) - arm_spe__synth_memory_level(record, &data_src); + arm_spe__synth_memory_level(speq, record, &data_src); if (record->type & (ARM_SPE_TLB_ACCESS | ARM_SPE_TLB_MISS)) { data_src.mem_dtlb = PERF_MEM_TLB_WK;