From: Matt Turner <mattst88@gmail.com>
To: Richard Henderson <richard.henderson@linaro.org>,
Magnus Lindholm <linmag7@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>
Cc: linux-alpha@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org,
Matt Turner <mattst88@gmail.com>
Subject: [PATCH v5 10/11] alpha/perf: add ProfileMe sample filters
Date: Tue, 03 Nov 2026 15:37:43 -0500 [thread overview]
Message-ID: <20261103-alpha-profileme-v5-10-bbe3937fbf3a@gmail.com> (raw)
In-Reply-To: <20261103-alpha-profileme-v5-0-bbe3937fbf3a@gmail.com>
ProfileMe samples any fetched instruction, including those killed on a
wrong path, and what happened to it is only in the PERF_SAMPLE_RAW data.
Add three config1 bits that keep only the samples of instructions that:
retired retired. VAL says so for an instruction that did not trap,
and the trap type for one that did.
mispredict were mispredicted conditional branches.
trapped trapped, mispredicts included, or caused an ITB miss,
Istream access violation or interrupt redirect.
A sample must match every bit that is set, as with Arm SPE's
event_filter. The driver drops the samples that do not, and they still
count as interrupts for throttling and frequency mode.
Suggested-by: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Matt Turner <mattst88@gmail.com>
---
arch/alpha/include/asm/wrperfmon.h | 11 +++++
arch/alpha/kernel/perf_event.c | 83 ++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+)
diff --git a/arch/alpha/include/asm/wrperfmon.h b/arch/alpha/include/asm/wrperfmon.h
index 489b3e073a32..6526438e73ee 100644
--- a/arch/alpha/include/asm/wrperfmon.h
+++ b/arch/alpha/include/asm/wrperfmon.h
@@ -106,14 +106,25 @@
#define EV67_I_STAT_MIS (1UL<<40)
/* I_STAT[TRAP_TYPE] values */
+#define EV67_TRAP_REPLAY 0
#define EV67_TRAP_DTB_DOUBLE_3 2
#define EV67_TRAP_DTB_DOUBLE_4 3
+#define EV67_TRAP_FEN 4
+#define EV67_TRAP_UNALIGNED 5
#define EV67_TRAP_DTB_SINGLE 6
+#define EV67_TRAP_DFAULT 7
+#define EV67_TRAP_OPCDEC 8
+#define EV67_PCTR_VAL (1UL<<1)
#define EV67_PCTR_PM_KILLED_BM (1UL<<26)
/* PMPC bits 63:2 hold the profiled PC. Bit 0 set means a PALmode address. */
#define EV67_PMPC_PAL (1UL<<0)
#define EV67_PMPC_PC_MASK (~3UL)
+/* PMPC[14:0] of the redirect traps, which do not set I_STAT[TRP] */
+#define EV67_PMPC_PAL_OFFSET_MASK 0x7fffUL
+#define EV67_PMPC_IACV 0x0481
+#define EV67_PMPC_ITB_MISS 0x0581
+#define EV67_PMPC_INTERRUPT 0x0681
#endif
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c
index 7f53aea261b0..bed671fe726d 100644
--- a/arch/alpha/kernel/perf_event.c
+++ b/arch/alpha/kernel/perf_event.c
@@ -39,6 +39,13 @@
#define ALPHA_PERF_CONFIG_EVENT 0xffULL
#define ALPHA_PERF_CONFIG_PROFILEME BIT_ULL(8)
#define ALPHA_PERF_CONFIG_RANDOMIZE BIT_ULL(9)
+/* attr.config1 of a ProfileMe event: keep only samples of these insns. */
+#define ALPHA_PERF_CONFIG1_RETIRED BIT_ULL(0)
+#define ALPHA_PERF_CONFIG1_MISPREDICT BIT_ULL(1)
+#define ALPHA_PERF_CONFIG1_TRAPPED BIT_ULL(2)
+#define ALPHA_PERF_CONFIG1_FILTERS (ALPHA_PERF_CONFIG1_RETIRED | \
+ ALPHA_PERF_CONFIG1_MISPREDICT | \
+ ALPHA_PERF_CONFIG1_TRAPPED)
/* hw_perf_event.flags */
#define ALPHA_PERF_FLAG_PROFILEME 0x1
@@ -257,11 +264,17 @@ static int ev67_raw_event_valid(u64 config)
PMU_FORMAT_ATTR(event, "config:0-7");
PMU_FORMAT_ATTR(profileme, "config:8");
PMU_FORMAT_ATTR(randomize, "config:9");
+PMU_FORMAT_ATTR(retired, "config1:0");
+PMU_FORMAT_ATTR(mispredict, "config1:1");
+PMU_FORMAT_ATTR(trapped, "config1:2");
static struct attribute *ev67_format_attrs[] = {
&format_attr_event.attr,
&format_attr_profileme.attr,
&format_attr_randomize.attr,
+ &format_attr_retired.attr,
+ &format_attr_mispredict.attr,
+ &format_attr_trapped.attr,
NULL,
};
@@ -807,6 +820,12 @@ static int __hw_perf_event_init(struct perf_event *event)
return -EINVAL;
hwc->flags = profileme ? ALPHA_PERF_FLAG_PROFILEME : 0;
+ if (attr->config1 & ~ALPHA_PERF_CONFIG1_FILTERS)
+ return -EINVAL;
+ if (attr->config1 && !profileme)
+ return -EINVAL;
+ hwc->config = attr->config1;
+
if (attr->type == PERF_TYPE_RAW &&
(attr->config & ALPHA_PERF_CONFIG_RANDOMIZE)) {
if (!profileme)
@@ -1022,6 +1041,62 @@ static bool alpha_profileme_trp(unsigned long i_stat, unsigned long pctr_ctl)
return !(pctr_ctl & EV67_PCTR_PM_KILLED_BM) && (i_stat & EV67_I_STAT_TRP);
}
+/*
+ * VAL says whether an instruction that did not trap retired. For one that
+ * did, the trap type decides: these faults abort it, to be replayed,
+ * refetched after a fill, or emulated. Other traps, mispredicts among
+ * them, are counted as retired.
+ */
+static bool alpha_profileme_retired(unsigned long i_stat,
+ unsigned long pctr_ctl)
+{
+ if (pctr_ctl & EV67_PCTR_PM_KILLED_BM)
+ return false;
+ if (!(i_stat & EV67_I_STAT_TRP))
+ return pctr_ctl & EV67_PCTR_VAL;
+ if (i_stat & EV67_I_STAT_MIS)
+ return true;
+
+ switch ((i_stat >> EV67_I_STAT_TRAP_TYPE_SHIFT) &
+ EV67_I_STAT_TRAP_TYPE_MASK) {
+ case EV67_TRAP_REPLAY:
+ case EV67_TRAP_DTB_DOUBLE_3:
+ case EV67_TRAP_DTB_DOUBLE_4:
+ case EV67_TRAP_FEN:
+ case EV67_TRAP_UNALIGNED:
+ case EV67_TRAP_DTB_SINGLE:
+ case EV67_TRAP_DFAULT:
+ case EV67_TRAP_OPCDEC:
+ return false;
+ default:
+ return true;
+ }
+}
+
+/* What the profiled instruction did, as config1 filter bits. */
+static u64 alpha_profileme_status(unsigned long i_stat,
+ unsigned long pctr_ctl, unsigned long pmpc)
+{
+ u64 status = 0;
+
+ if (alpha_profileme_retired(i_stat, pctr_ctl))
+ status |= ALPHA_PERF_CONFIG1_RETIRED;
+ if (alpha_profileme_trp(i_stat, pctr_ctl)) {
+ status |= ALPHA_PERF_CONFIG1_TRAPPED;
+ if (i_stat & EV67_I_STAT_MIS)
+ status |= ALPHA_PERF_CONFIG1_MISPREDICT;
+ } else if (pmpc & EV67_PMPC_PAL) {
+ switch (pmpc & EV67_PMPC_PAL_OFFSET_MASK) {
+ case EV67_PMPC_IACV:
+ case EV67_PMPC_ITB_MISS:
+ case EV67_PMPC_INTERRUPT:
+ status |= ALPHA_PERF_CONFIG1_TRAPPED;
+ break;
+ }
+ }
+ return status;
+}
+
static u64 alpha_profileme_mem_op(unsigned long pc)
{
u32 insn;
@@ -1083,6 +1158,14 @@ static void alpha_perf_event_profileme(struct perf_event *event,
local64_add(ovr, &hwc->period_left);
}
+ /* A dropped sample still counts, for throttling and frequency mode. */
+ if ((alpha_profileme_status(i_stat, pctr_ctl, pmpc) & hwc->config) !=
+ hwc->config) {
+ if (alpha_perf_event_set_period(event, hwc, 0))
+ perf_event_account_interrupt(event);
+ return;
+ }
+
/*
* Attribute the sample to the profiled instruction rather than to
* wherever the interrupt landed. perf takes the sample's mode,
--
2.55.0
next prev parent reply other threads:[~2026-11-03 20:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 20:37 [PATCH v5 00/11] alpha/perf: add ProfileMe sampling Matt Turner
2026-11-03 20:37 ` [PATCH v5 01/11] alpha/perf: pass PERFMON_CMD_LOGGING_ALL to the logging options call Matt Turner
2026-11-03 20:37 ` [PATCH v5 02/11] alpha/perf: add sysfs format and event attributes Matt Turner
2026-11-03 20:37 ` [PATCH v5 03/11] alpha/perf: clear PERF_HES_UPTODATE when an event starts counting Matt Turner
2026-11-03 20:37 ` [PATCH v5 04/11] alpha/perf: do not report user registers from the entry code Matt Turner
2026-11-03 20:37 ` [PATCH v5 05/11] alpha/perf: implement ProfileMe sampling Matt Turner
2026-11-03 20:37 ` [PATCH v5 06/11] alpha/perf: attach ProfileMe status as PERF_SAMPLE_RAW data Matt Turner
2026-11-03 20:37 ` [PATCH v5 07/11] alpha/perf: optionally randomize the ProfileMe sampling interval Matt Turner
2026-11-03 20:37 ` [PATCH v5 08/11] alpha/perf: report the ProfileMe window count as the sample weight Matt Turner
2026-11-03 20:37 ` [PATCH v5 09/11] alpha/perf: report the data source of ProfileMe DTB misses Matt Turner
2026-11-03 20:37 ` Matt Turner [this message]
2026-11-03 20:37 ` [PATCH v5 11/11] alpha/perf: sample only retired instructions for precise events Matt Turner
2026-11-03 23:42 ` [PATCH v5 00/11] alpha/perf: add ProfileMe sampling Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103-alpha-profileme-v5-10-bbe3937fbf3a@gmail.com \
--to=mattst88@gmail.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linmag7@gmail.com \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®