Re: [PATCH v5 00/11] alpha/perf: add ProfileMe sampling
From: Ian Rogers
Date: Tue Nov 03 2026 - 18:44:46 EST
On Tue, Nov 3, 2026 at 12:37 PM Matt Turner <mattst88@xxxxxxxxx> wrote:
>
> The 21264 from EV67 on, and the 21364, have a second performance counter
> mode, ProfileMe, alongside the Aggregate mode that the driver uses today.
> An Aggregate mode sample reports the PC where the overflow interrupt was
> taken. On an EV7 that is anywhere from 15 instructions before to 12
> after the one that overflowed the counter, which makes perf annotate
> output close to useless. In ProfileMe mode the CPU picks one fetched
> instruction, follows it down the pipeline, and reports its PC along with
> what happened to it: whether it retired, whether it trapped and why,
> whether it was a mispredicted branch, stalled before map, or was killed
> on a wrong path, and what PCTR1 counted while it was in flight.
>
> Patch 1 fixes a constant passed to the wrong PALcode call, with no
> functional change. Patch 2 adds the sysfs format and event attributes
> the perf tool needs to name raw events. Patch 3 fixes counts lost when
> an event is stopped before its first start, and patch 4 stops reporting
> user registers that the entry code has not saved yet. Patch 5 adds
> ProfileMe sampling, selected with precise_ip or a new profileme config
> bit, so cycles:p and perf record's default event use it. Patch 6
> attaches the status registers to each sample as PERF_SAMPLE_RAW data,
> and patch 7 adds an option to randomize the sampling interval so that it
> cannot lock onto a loop. Patches 8 and 9 report what PCTR1 counted as
> the sample weight and the data source of DTB misses. Patch 10 adds
> filters that keep only retired, mispredicted or trapping instructions,
> and patch 11 makes precise events sample only retired ones.
>
> A separate series for perf-tools-next adds a decoder for the raw data
> to perf report -D and perf script -D, and a script that sums the status
> by symbol or by instruction, in the style of DCPI.
>
> The two modes cannot run at the same time, because PCTR_CTL[SL0] sets
> the mode for both counters. A ProfileMe event is scheduled alone, and
> perf multiplexes it with any other hardware events. perf stat does not
> ask for precise events, so it keeps using Aggregate mode.
>
> To try it:
>
> perf record -e cycles:p -- ./workload
> perf annotate
>
> I tested this on an AlphaServer ES47 (EV7). Samples from a
> 16-instruction loop land on all 16 instructions rather than on 4 PCs.
> DTB misses and unaligned traps are attributed to the faulting load. A
> branch on random data shows up as mispredicted in 21% of its samples,
> and in 0% with sorted data. A 12 minute perf record -a while building
> git took 4.45 million samples with no warnings. Sampling every 10000
> instructions, which used to wedge the CPU, ran 66 times without a hang.
> With precise_ip, killed instructions went from 67% of the samples of a
> mispredicting loop to none. On two CPUs, this version survived 62 runs
> that mix sampling, filters, context switches and multiplexing, with no
> warnings.
>
> Signed-off-by: Matt Turner <mattst88@xxxxxxxxx>
Hi Matt,
Thanks for v5, and for turning the suggestions around so quickly with
measurements to back each one up. Patch 8 looks good to me; a few
comments on the rest (appologies, I'm using Gemini to help me be
cleverer than I am):
Patch 5: I think Sashiko's report is right. With idx forced to 0 in
ProfileMe mode, a PCTR1 overflow still pending when an Aggregate event
is multiplexed out gets taken as a window close: it adds a bogus 2^20
to the count and emits a sample from a stale PMPC, possibly another
task's. That's the mirror image of the false sample the commit message
documents for the other direction.
In both cases the interrupt arrives for a counter that hasn't wrapped
since it was last written, whereas after a real overflow or window
close the counter sits just past zero. Could the handler drop an
interrupt when the counter hasn't wrapped relative to prev_count? It
would need some headroom: a counting event's period is 2^20 - 1, so
its counter starts at 1, and a real overflow, which leaves it just
past zero, would look unwrapped too. Capping left at half the counter
range, as armpmu_event_set_period() does, keeps the two cases apart.
That would fix both directions, and the caveat could come out of the
commit message.
Patch 9: Now that patch 11 drops DTB miss samples from cycles:p, it
may be worth giving retired loads and stores a data source too. As
PALcode fills the TB, an access that retired without a DTB miss trap
must have hit, so mem_dtlb = PERF_MEM_TLB_L1 | PERF_MEM_TLB_HIT. The
memory sort keys would then show DTB hits and misses side by side for
cpu/cycles,profileme/. LDA/LDAH and the ldq_u UNOP would need leaving
out, as they don't access memory.
Loads into $31/$f31 need care either way. As the comment in
do_page_fault() says, as of EV6 they're prefetches, which never fault
(or are suppressed by the PALcode). If a prefetch that misses the DTB
is dropped without a trap, they'd need leaving out of the hits too. If
it does trap, patch 9 reports it as a LOAD, where PERF_MEM_OP_PFETCH
would be more accurate. Running your one-word-per-page test with loads
into $31 would show which.
Patch 11: Kept samples still carry the full period, so with -F the
sample rate, and perf report's approximate event count, fall by the
killed fraction: to about a third on your mispredict loop. That seems
the right trade-off, and it's what IBS's swfilt does with the samples
it discards, but it may deserve a sentence in the commit message.
For the next spin of the tools series, alpha-profileme.py wants the
same PM_KILLED_BM check before it trusts TRP and MIS. Its example also
records instructions:p, which after patch 11 has no killed samples, so
the killed% and invalid% columns would always read 0;
cpu/instructions,profileme/ keeps them.
Two possible follow-ups, neither of which needs to hold up this
series. perf mem has no Alpha events yet; cpu/cycles,trapped/p would
be a natural default, or cpu/cycles,profileme/ if retired accesses get
a data source. And as the driver already works out the profiled
instruction's mode for the trap frame swap, ProfileMe events could
honor exclude_user and exclude_kernel by dropping samples, as IBS's
swfilt does, with PALmode counting as kernel. PERF_PMU_CAP_NO_EXCLUDE
is PMU wide, so event_init would then reject the exclude bits itself
for Aggregate events. That would let unprivileged users run perf
record at the default perf_event_paranoid of 2, where the tool sets
exclude_kernel for them.
Thanks,
Ian
> ---
> Changes in v5:
> - Patch 5: refuse precise_ip 3, as a sample with a PALmode PMPC keeps
> the interrupted PC. Thanks to Magnus Lindholm.
> - New patches 8 to 11, from Ian Rogers' suggestions: the sample weight,
> the data source of DTB misses, config1 filters, and retired-only
> precise samples. The last changes what a default perf record shows.
> - Link to v4: https://patch.msgid.link/20261102-alpha-profileme-v4-0-61e00f5e1da8@xxxxxxxxx
>
> Changes in v4:
> - Patch 4: move __entry_save_end past the r16-r18 stores in entSys,
> as PAL_callsys does not save them and interrupts are still enabled
> there.
> - Patch 5: report the user registers when the profiled instruction is
> in the entry code but the interrupt was taken after it, since
> perf_get_regs_user() sees the PMPC rather than the interrupted PC.
> - Link to v3: https://patch.msgid.link/20261101-alpha-profileme-v3-0-92d511b5a044@xxxxxxxxx
>
> Changes in v3:
> - New patch 3: clear PERF_HES_UPTODATE when an event starts counting,
> so that a stop before the first start does not lose the count.
> - New patch 4: report no user registers for a sample taken in the entry
> code, where the frame at task_pt_regs() is not complete. An interrupt
> nested on one taken there is still not caught.
> - Patch 5: a user instruction whose interrupt is taken in the kernel now
> reports its PC with no registers or user stack, as the frame at
> task_pt_regs() may not be built yet. Thanks to Magnus Lindholm for
> finding this and for the fix.
> - Patch 5: also move the counter away from overflow when a ProfileMe
> event is removed, or stopped without PERF_EF_UPDATE, as
> alpha_pmu_del() does not go through alpha_pmu_stop().
> - Patch 5: ignore an interrupt that was pending when the event was
> stopped. Document that rewriting a counter does not cancel one.
> - Link to v2: https://patch.msgid.link/20261030-alpha-profileme-v2-0-c702f1c65272@xxxxxxxxx
>
> Changes in v2:
> - Patch 1: explain why bit 0 clear means all processes, although the
> Architecture Reference Manual says otherwise.
> - Patch 3: fix a CPU wedge during high-rate ProfileMe sampling. The
> ProfileMe counters are now written twice, and a stopped counter is
> moved away from overflow, as EV67 HRM PALcode restrictions 32 and 38
> require.
> - Patch 3: set the profiled PC in place in the trap frame of the
> instruction's mode instead of in a pt_regs copy on the stack, so
> sampled registers and stack values are those of the right frame.
> A kernel instruction whose interrupt is taken in user mode gets a
> per-CPU frame holding only its PC, so the user frame is not changed.
> - Patch 4: drop the reserved field and pack the 64-bit fields of
> struct alpha_profileme_sample, so they are 8-byte aligned in the
> sample record and the record needs no padding. This changes the raw
> data layout.
> - Patch 5: compute the jitter with mul_u64_u32_shr() and saturate the
> sum, so that large periods cannot overflow.
> - Link to v1: https://patch.msgid.link/20261028-alpha-profileme-v1-0-d44b52bf2500@xxxxxxxxx
>
> ---
> Matt Turner (11):
> alpha/perf: pass PERFMON_CMD_LOGGING_ALL to the logging options call
> alpha/perf: add sysfs format and event attributes
> alpha/perf: clear PERF_HES_UPTODATE when an event starts counting
> alpha/perf: do not report user registers from the entry code
> alpha/perf: implement ProfileMe sampling
> alpha/perf: attach ProfileMe status as PERF_SAMPLE_RAW data
> alpha/perf: optionally randomize the ProfileMe sampling interval
> alpha/perf: report the ProfileMe window count as the sample weight
> alpha/perf: report the data source of ProfileMe DTB misses
> alpha/perf: add ProfileMe sample filters
> alpha/perf: sample only retired instructions for precise events
>
> arch/alpha/include/asm/perf_event.h | 2 +
> arch/alpha/include/asm/ptrace.h | 12 +
> arch/alpha/include/asm/wrperfmon.h | 36 +++
> arch/alpha/include/uapi/asm/perf_event.h | 31 ++
> arch/alpha/kernel/entry.S | 9 +
> arch/alpha/kernel/perf_event.c | 535 ++++++++++++++++++++++++++++++-
> arch/alpha/kernel/perf_regs.c | 13 +
> 7 files changed, 625 insertions(+), 13 deletions(-)
> ---
> base-commit: 330517c63aa9b48227b6ab45f01003effac77ae4
> change-id: 20261024-alpha-profileme-6e98a977cb54
>
> Best regards,
> --
> Matt Turner <mattst88@xxxxxxxxx>
>