Re: [PATCH 2/4] perf arm_spe: Turn event name mappings into an array

From: James Clark

Date: Thu Apr 02 2026 - 06:00:13 EST




On 02/04/2026 10:13 am, Leo Yan wrote:
On Wed, Apr 01, 2026 at 03:25:50PM +0100, James Clark wrote:
This is so we can have a single function that prints events and can be
used with multiple mappings from different CPUs. Remove any bit that was
printed so that later we can print out the remaining unknown impdef
bits.

No functional changes intended.

Signed-off-by: James Clark <james.clark@xxxxxxxxxx>
---
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 88 +++++++++++-----------
1 file changed, 43 insertions(+), 45 deletions(-)

diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index 5769ba2f4140..c880b0dec3a1 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -276,6 +276,48 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
return ret;
}
+struct ev_string {
+ u8 event;
+ const char *desc;
+};

Maybe we can have more ambition to define a more general structure:

struct packet_field_string {
u64 bit_mask;
u64 bit_val;
const char *desc;
};

Thus, this also can be used by other bit fields decoding. We can do
this now or if later refactor for other packets.

Either way is fine for me:

Reviewed-by: Leo Yan <leo.yan@xxxxxxx>


Thanks. I think I'll leave it as it is, there's a risk of making it too generic and then it doesn't fit any other use case anyway. We can always add it later.

+
+static const struct ev_string common_ev_strings[] = {
+ { .event = EV_EXCEPTION_GEN, .desc = "EXCEPTION-GEN" },
+ { .event = EV_RETIRED, .desc = "RETIRED" },
+ { .event = EV_L1D_ACCESS, .desc = "L1D-ACCESS" },
+ { .event = EV_L1D_REFILL, .desc = "L1D-REFILL" },
+ { .event = EV_TLB_ACCESS, .desc = "TLB-ACCESS" },
+ { .event = EV_TLB_WALK, .desc = "TLB-REFILL" },
+ { .event = EV_NOT_TAKEN, .desc = "NOT-TAKEN" },
+ { .event = EV_MISPRED, .desc = "MISPRED" },
+ { .event = EV_LLC_ACCESS, .desc = "LLC-ACCESS" },
+ { .event = EV_LLC_MISS, .desc = "LLC-REFILL" },
+ { .event = EV_REMOTE_ACCESS, .desc = "REMOTE-ACCESS" },
+ { .event = EV_ALIGNMENT, .desc = "ALIGNMENT" },
+ { .event = EV_TRANSACTIONAL, .desc = "TXN" },
+ { .event = EV_PARTIAL_PREDICATE, .desc = "SVE-PARTIAL-PRED" },
+ { .event = EV_EMPTY_PREDICATE, .desc = "SVE-EMPTY-PRED" },
+ { .event = EV_L2D_ACCESS, .desc = "L2D-ACCESS" },
+ { .event = EV_L2D_MISS, .desc = "L2D-MISS" },
+ { .event = EV_CACHE_DATA_MODIFIED, .desc = "HITM" },
+ { .event = EV_RECENTLY_FETCHED, .desc = "LFB" },
+ { .event = EV_DATA_SNOOPED, .desc = "SNOOPED" },
+ { .event = EV_STREAMING_SVE_MODE, .desc = "STREAMING-SVE" },
+ { .event = EV_SMCU, .desc = "SMCU" },
+ { .event = 0, .desc = NULL },
+};
+
+static u64 print_event_list(int *err, char **buf, size_t *buf_len,
+ const struct ev_string *ev_strings, u64 payload)
+{
+ for (const struct ev_string *ev = ev_strings; ev->desc != NULL; ev++) {
+ if (payload & BIT(ev->event))
+ arm_spe_pkt_out_string(err, buf, buf_len, " %s", ev->desc);
+ payload &= ~BIT(ev->event);
+ }
+ return payload;
+}
+
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
char *buf, size_t buf_len)
{
@@ -283,51 +325,7 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
int err = 0;
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
-
- if (payload & BIT(EV_EXCEPTION_GEN))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
- if (payload & BIT(EV_RETIRED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
- if (payload & BIT(EV_L1D_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
- if (payload & BIT(EV_L1D_REFILL))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
- if (payload & BIT(EV_TLB_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
- if (payload & BIT(EV_TLB_WALK))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
- if (payload & BIT(EV_NOT_TAKEN))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
- if (payload & BIT(EV_MISPRED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
- if (payload & BIT(EV_LLC_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
- if (payload & BIT(EV_LLC_MISS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
- if (payload & BIT(EV_REMOTE_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
- if (payload & BIT(EV_ALIGNMENT))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
- if (payload & BIT(EV_TRANSACTIONAL))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
- if (payload & BIT(EV_PARTIAL_PREDICATE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
- if (payload & BIT(EV_EMPTY_PREDICATE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
- if (payload & BIT(EV_L2D_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
- if (payload & BIT(EV_L2D_MISS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
- if (payload & BIT(EV_CACHE_DATA_MODIFIED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
- if (payload & BIT(EV_RECENTLY_FETCHED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
- if (payload & BIT(EV_DATA_SNOOPED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
- if (payload & BIT(EV_STREAMING_SVE_MODE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
- if (payload & BIT(EV_SMCU))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
+ print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
return err;
}

--
2.34.1