[PATCH 11/12] perf arm_spe: Set HITM flag
Leo Yan
leo.yan at arm.com
Fri Jun 13 08:53:44 PDT 2025
Since FEAT_SPEv1p4, Arm SPE provides extra two events "Cache data
modified" and "Data snooped".
Set the snoop mode as:
- If both the "Cache data modified" event and the "Data snooped" event
are set, which indicates a load operation that snooped from a outside
cache and hit a modified copy, set the HITM flag to inspect false
sharing.
- If the snooped event bit is not set, and the snooped event has been
supported by the hardware, set as NONE mode (no snoop operation).
- If the snooped event bit is not set, and the event is not supported or
absent the events info in the meta data, set as NA mode (not
available).
Don't set any mode for only "Cache data modified" event, as it hits a
local modified copy.
Signed-off-by: Leo Yan <leo.yan at arm.com>
---
tools/perf/util/arm-spe-decoder/arm-spe-decoder.h | 2 ++
tools/perf/util/arm-spe.c | 26 +++++++++++++++++++++--
2 files changed, 26 insertions(+), 2 deletions(-)
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 90c76928c7bf1b35cec538abdb0e88d6083fe81b..a2b48b0c87712f232587023eeaa66a9b83aed382 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_FETCH 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 8e93b0d151a98714d0c5e5f6ceec386a2aa63ad0..8a889f727f9cd5351b4ca027935112eddd16ea6c 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -903,9 +903,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)
@@ -916,6 +919,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_EVENTS] & 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;
}
@@ -971,7 +993,7 @@ static u64 arm_spe__synth_data_source(struct arm_spe_queue *speq,
return 0;
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;
--
2.34.1
More information about the linux-arm-kernel
mailing list