On Tue, Nov 03, 2026 at 12:46:24PM -0800, Yabin Cui wrote:
...
> In field telemetry and local ftrace on Pixel devices (prior to
> 18049c8cff9c, so __GFP_NORETRY was already in place), we observed heavy
> rb_alloc_aux() -> __alloc_pages_direct_compact() stalls alongside
> kcompactd0 pinned on big cores scanning order-9, and this accounted for
> >20% of all perceptible app kills (via lmkd) across dogfood devices
> until we stopped high-order AUX allocations.
Thanks for the detailed explanation. My understanding is that repeated
reclaim/compaction during AUX allocation raises memory PSI and can lead
to lmkd killing applications. The problem to address is therefore the
cost of obtaining higher-order pages under memory fragmentation.
> Initially we worked around this in userspace (simpleperf) by setting
> perf_event_attr::aux_watermark = 4096 so get_order(watermark) == 0. That
> was fine for CoreSight ETR (which uses its own separate scatter-gather
> buffer and only copies into AUX on flush/stop), but when enabling TRBE
> (and SPE) it caused hardware maintenance interrupts every 4 KiB instead
> of every 2 MiB. Also, in overwrite/snapshot mode rb_alloc_aux() ignores
> aux_watermark and uses ilog2(nr_pages). That is why I sent 18049c8cff9c.
Agreed. Reducing watermark to 4096 also increases maintenance interrupt
frequency for SPE/TRBE. We should refine buffer allocation rather than
using watermark as a workaround.
> ### Possible solutions
>
> For PMUs without PERF_PMU_CAP_AUX_NO_SG (such as SPE, TRBE, and modern
> Intel PT), higher-order AUX pages are an opportunistic optimization
> rather than a functional requirement -- very similar to THP allocations
> on fault (GFP_TRANSHUGE_LIGHT) or opportunistic high-order slabs in SLUB
> (allocate_slab()).
>
> Instead of reverting to GFP_KERNEL reclaim/compaction for all high-order
> attempts, could we do the following?
>
> 1. Make opportunistic high-order AUX allocations no-reclaim:
> When !(event->pmu->capabilities & PERF_PMU_CAP_AUX_NO_SG) and
> order > 0, clear __GFP_RECLAIM (and add __GFP_NOMEMALLOC, matching
> SLUB's allocate_slab() and GFP_TRANSHUGE_LIGHT):
>
> gfp_t gfp = PERF_AUX_GFP;
>
> if (order && !has_no_sg)
> gfp = (PERF_AUX_GFP | __GFP_NOMEMALLOC) & ~__GFP_RECLAIM;
>
> When order falls back to 0 (or when PERF_PMU_CAP_AUX_NO_SG is set),
> keep PERF_AUX_GFP so single-page allocations still reclaim normally
> under memory pressure.
>
> That way, when free order-9 / order-4 blocks exist, SPE and TRBE get
> them immediately for PMD / contiguous-PTE vmap() mappings (and pages
> stay grouped together); when memory is fragmented on a long-running
> device, high-order probes fail fast on the freelist without waking
> kcompactd/kswapd or triggering direct compaction and reclaim.
This looks reasonable for me: try to obtain larger blocks cheaply, then
then retain the PERF_AUX_GFP policy for order-0 allocations. I also
agree with preserving the allocation policy for PERF_PMU_CAP_AUX_NO_SG
case.
Could you compare the memory PSI stall deltas before and after applying
this option? I think measurements from your production devices would be
convinced evidence for benefits.
> 2. Clamp max_order in rb_alloc_aux() after fallback:
> If rb_alloc_aux_page() requested `order` and had to fall back to a
> smaller order, update `max_order = page_private(page)` in
> rb_alloc_aux() so subsequent iterations for the rest of the buffer do
> not keep re-probing higher orders that just failed.
This also can avoid reclaim repeatedly, but the side effect is subsequent
iterations would no longer try high order, which have no chance to
benefit from large mapping.
I would prefer to evaluate option 1 first.
> (Optionally, if server/benchmark workloads ever want synchronous
> compaction to form huge AUX mappings even on fragmented hosts, that could
> be gated behind an opt-in attr/sysfs knob similar to THP defrag modes,
> with light/no-reclaim as the default.)
I will follow up with Will separately about the userspace interface.
> Would this approach work for your SPE/TRBE use cases? Happy to help test
> on our side.
If option 1 works, we can confidently revert 18049c8cff9c, as it would
restore higher-order allocations for TRBE/SPE without introducing the
regression you mentioned.
Thanks,
Leo
On 26/10/2026 05:48, Amir Ayupov wrote:
> Drivers outside the PMU driver may need to know whether the local CPU's
> PMU implements a common event before relying on it, for example a trace
> unit driver checking that the PMU counts its external outputs as
> TRCEXTOUTn.
>
> Add pmuv3_event_implemented() to the arm64 asm/arm_pmuv3.h, next to
> read_pmceid0() and read_pmceid1(). It reads PMCEID0/1 on the calling CPU:
> events 0x0000-0x003f are reported in bits [31:0], and the common events
> from ARMV8_PMUV3_EXT_COMMON_EVENT_BASE in bits [63:32] from PMUv3p1. Move
> ARMV8_PMUV3_EXT_COMMON_EVENT_BASE next to the event numbers in
> linux/perf/arm_pmuv3.h so it is available without CONFIG_ARM_PMU.
>
> Suggested-by: James Clark <james.clark(a)linaro.org>
> Assisted-by: Devmate:Opus-5.5
> Signed-off-by: Amir Ayupov <aaupov(a)fb.com>
> ---
> arch/arm64/include/asm/arm_pmuv3.h | 19 +++++++++++++++++++
> include/linux/perf/arm_pmu.h | 1 -
> include/linux/perf/arm_pmuv3.h | 3 +++
> 3 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
> index 8a777dec8d88a..acd62c4f16743 100644
> --- a/arch/arm64/include/asm/arm_pmuv3.h
> +++ b/arch/arm64/include/asm/arm_pmuv3.h
> @@ -173,6 +173,25 @@ static inline bool pmuv3_implemented(int pmuver)
> pmuver == ID_AA64DFR0_EL1_PMUVer_NI);
> }
>
> +/*
> + * Whether this CPU's PMU implements a common event, as reported by
> + * PMCEID{0,1}: events 0x0000-0x003f in bits [31:0], and from PMUv3p1 events
> + * 0x4000-0x403f in bits [63:32], which read as zero before PMUv3p1.
> + * Must run on the CPU whose PMU is queried.
> + */
> +static inline bool pmuv3_event_implemented(u16 event)
> +{
> + bool ext = event >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE;
> + u16 id = ext ? event - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE : event;
> + u64 pmceid;
> +
> + if (id >= 64 || !pmuv3_implemented(read_pmuver()))
> + return false;
> +
> + pmceid = id < 32 ? :() : read_pmceid1();
> + return pmceid & BIT_ULL(id % 32 + (ext ? 32 : 0));
> +}
> +
> static inline bool is_pmuv3p4(int pmuver)
> {
> return pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P4;
> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> index 02d2c7f45b527..792283d29d7b5 100644
> --- a/include/linux/perf/arm_pmu.h
> +++ b/include/linux/perf/arm_pmu.h
> @@ -124,7 +124,6 @@ struct arm_pmu {
> u64 reg_brbidr;
> #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40
> DECLARE_BITMAP(pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
> -#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000
> DECLARE_BITMAP(pmceid_ext_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
Could we not avoid this change ? Or why not move both of the definitions ?
Also, I would need an ACK from the arm_pmu maintainers to accept this
change via coresight tree.
Cheers
Suzuki
>
> /* Only to be used by ACPI probing code */
> diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h
> index d698efba28a27..c21f185a283d6 100644
> --- a/include/linux/perf/arm_pmuv3.h
> +++ b/include/linux/perf/arm_pmuv3.h
> @@ -78,6 +78,9 @@
> #define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND 0x003E
> #define ARMV8_PMUV3_PERFCTR_STALL_SLOT 0x003F
>
> +/* Base of the common events reported in PMCEID{0,1}[63:32] from PMUv3p1 */
> +#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000
> +
> /* Statistical profiling extension microarchitectural events */
> #define ARMV8_SPE_PERFCTR_SAMPLE_POP 0x4000
> #define ARMV8_SPE_PERFCTR_SAMPLE_FEED 0x4001
On 26/10/2026 05:48, Amir Ayupov wrote:
> A feature loads on a device when the two share any match flag. That works
> for device classes, where a feature wants any one of them, but not for
> capabilities a device may or may not have: a feature that sets a class
> and a capability would still load on a device of that class without the
> capability.
>
> Split the match flags into CS_CFG_MATCH_CLASS_MASK for device classes and
> CS_CFG_MATCH_CAP_MASK for capabilities. A feature now loads on a device
> that shares one of its classes and has all of its capabilities. Check
> this once in cscfg_load_feat_csdev(), which both the feature and the
> device registration paths call. No capability flags are defined yet, so
> matching is unchanged.
>
> Assisted-by: Devmate:Opus-5.5
> Signed-off-by: Amir Ayupov <aaupov(a)fb.com>
> ---
> .../hwtracing/coresight/coresight-config.h | 8 ++++
> .../hwtracing/coresight/coresight-syscfg.c | 37 +++++++++++++------
> 2 files changed, 34 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index ae6295e308131..f04e73b91d9a6 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -7,6 +7,7 @@
> #ifndef _CORESIGHT_CORESIGHT_CONFIG_H
> #define _CORESIGHT_CORESIGHT_CONFIG_H
>
> +#include <linux/bits.h>
> #include <linux/cleanup.h>
> #include <linux/coresight.h>
> #include <linux/types.h>
> @@ -30,6 +31,13 @@
> */
> #define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */
> #define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */
> +#define CS_CFG_MATCH_CLASS_MASK GENMASK_U32(7, 0)
> +
> +/*
> + * flags defining device capabilities a feature can require. A feature loads on
> + * a device that matches one of its classes and has all of its capabilities.
> + */
> +#define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8)
>
> /* flags defining device instance matching - used in config match desc data. */
> #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index a816c22c87bc8..3ee104e94a4cd 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -171,8 +171,22 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc
> return feat_csdev;
> }
>
> -/* load one feature into one coresight device */
> +static bool cscfg_match_feat_csdev(u32 feat_flags, u32 csdev_flags)
> +{
> + /* The device must be in one of the feature's classes */
> + if (!(feat_flags & csdev_flags & CS_CFG_MATCH_CLASS_MASK))
> + return false;
> +
> + /* The device must have every capability the feature requires */
> + if (feat_flags & ~csdev_flags & CS_CFG_MATCH_CAP_MASK)
> + return false;
Please could you address the following comment ?
https://lore.kernel.org/linux-arm-kernel/82adee03-a169-4106-99f2-7624a49260…
Cheers
Suzuki
> +
> + return true;
> +}
> +
> +/* Load the feature into the device if it matches, otherwise skip it. */
> static int cscfg_load_feat_csdev(struct coresight_device *csdev,
> + u32 match_flags,
> struct cscfg_feature_desc *feat_desc,
> struct cscfg_csdev_feat_ops *ops)
> {
> @@ -183,6 +197,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev,
> if (!ops->load_feat)
> return -EINVAL;
>
> + if (!cscfg_match_feat_csdev(feat_desc->match_flags, match_flags))
> + return 0;
> +
> feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc);
> if (!feat_csdev)
> return -ENOMEM;
> @@ -212,11 +229,11 @@ static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc)
> int err;
>
> list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
> - if (csdev_item->match_flags & feat_desc->match_flags) {
> - err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops);
> - if (err)
> - return err;
> - }
> + err = cscfg_load_feat_csdev(csdev_item->csdev,
> + csdev_item->match_flags, feat_desc,
> + &csdev_item->ops);
> + if (err)
> + return err;
> }
> return 0;
> }
> @@ -739,11 +756,9 @@ static int cscfg_add_feats_csdev(struct coresight_device *csdev,
> return -EINVAL;
>
> list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
> - if (feat_desc->match_flags & match_flags) {
> - err = cscfg_load_feat_csdev(csdev, feat_desc, ops);
> - if (err)
> - break;
> - }
> + err = cscfg_load_feat_csdev(csdev, match_flags, feat_desc, ops);
> + if (err)
> + break;
> }
> return err;
> }
On 26/10/2026 05:48, Amir Ayupov wrote:
> Some CPUs count the trace unit's external outputs as the PMU common
> events TRCEXTOUT0-3 (0x4010-0x4013), which lets a configuration drive a
> PMU event from trace unit events. Other CPUs, Neoverse N1 for example,
> have no such events, and a feature relying on them would silently do
> nothing there.
>
> Detect at probe, on the trace unit's CPU, whether the PMU counts every
> external output: the trace unit has an external output for each of its
> events (caps.nr_event), and pmuv3_event_implemented() reports whether
> the PMU implements TRCEXTOUTn. Only check ETE: per its specification, an
> implemented TRCEXTOUTn event counts external output n, while whether that
> output is also an external input is IMPLEMENTATION DEFINED.
>
> Add a CS_CFG_MATCH_CAP_TRCEXTOUT capability match flag, set it on those
> trace units, and show it in the feature's configfs 'matches' attribute.
> With capabilities matched separately from the device class, a feature
> that requires it only loads on those trace units.
>
> Assisted-by: Devmate:Opus-5.5
> Signed-off-by: Amir Ayupov <aaupov(a)fb.com>
> ---
> .../hwtracing/coresight/coresight-config.h | 2 ++
> .../hwtracing/coresight/coresight-etm4x-cfg.c | 6 ++++-
> .../coresight/coresight-etm4x-core.c | 26 +++++++++++++++++++
> drivers/hwtracing/coresight/coresight-etm4x.h | 3 +++
> .../coresight/coresight-syscfg-configfs.c | 3 +++
> 5 files changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index 220bc54f8e5e1..4cf53230854d0 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -38,6 +38,8 @@
> * a device that matches one of its classes and has all of its capabilities.
> */
> #define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8)
> +/* the PMU counts the trace unit's external outputs as TRCEXTOUTn */
> +#define CS_CFG_MATCH_CAP_TRCEXTOUT BIT(8)
>
Please could we rename this to :
CS_CFG_MATCH_CAP_ETE_TRCEXTOUT
as this is only applicable for ETEs ?
> /*
> * Limit number of presets in a configuration
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> index 52cb036bb04b9..9e4dc5950c13d 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> @@ -176,9 +176,13 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev,
>
> int etm4_cscfg_register(struct coresight_device *csdev)
> {
> + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> struct cscfg_csdev_feat_ops ops;
> + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS;
>
> ops.load_feat = &etm4_cfg_load_feature;
> + if (drvdata->caps.trcextout)
> + match_flags |= CS_CFG_MATCH_CAP_TRCEXTOUT;
>
> - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops);
> + return cscfg_register_csdev(csdev, match_flags, &ops);
> }
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index af017bd8a5477..cb5fbb0279b88 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -30,6 +30,7 @@
> #include <linux/uaccess.h>
> #include <linux/perf_event.h>
> #include <linux/perf/arm_pmu.h>
> +#include <linux/perf/arm_pmuv3.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <linux/property.h>
> @@ -1399,6 +1400,29 @@ static void etm4_fixup_wrong_ccitmin(struct etmv4_caps *caps)
> }
> }
>
> +/*
> + * Whether the PMU counts each external output of this trace unit as
> + * TRCEXTOUTn. The trace unit has an external output for each of its events.
> + * Only ETE is checked: per its specification, an implemented TRCEXTOUTn event
> + * counts external output n.
> + *
> + * Must run on the CPU that owns the trace unit.
> + */
> +static bool etm4_pmu_counts_extout(struct etmv4_drvdata *drvdata)
> +{
> + int n;
> +
> + if (!etm4x_is_ete(drvdata) || !drvdata->caps.nr_event)
> + return false;
> +
> + for (n = 0; n < drvdata->caps.nr_event; n++) {
> + if (!pmuv3_event_implemented(ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 + n))
> + return false;
> + }
> +
> + return true;
> +}
> +
> static void etm4_init_arch_data(void *info)
> {
> u32 etmidr0;
> @@ -1562,6 +1586,8 @@ static void etm4_init_arch_data(void *info)
> /* NUMCNTR, bits[30:28] number of counters available for tracing */
> caps->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
>
> + caps->trcextout = etm4_pmu_counts_extout(drvdata);
> +
> coresight_clear_self_claim_tag_unlocked(csa);
> etm4_cs_lock(drvdata, csa);
> cpu_detect_trace_filtering(drvdata);
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 5417280cdb274..33994ad4b2641 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -868,6 +868,8 @@ enum etm_impdef_type {
> * @lpoverride: If the implementation can support low-power state over.
> * @skip_power_up: Indicates if an implementation can skip powering up
> * the trace unit.
> + * @trcextout: The trace unit is an ETE whose PMU counts its external
> + * outputs as TRCEXTOUTn.
We don't seem to be using this after the CSFG flag initialisation, in
which case could we directly call etm4_pmu_counts_extout() from
etm4_cscfg_register() ?
Suzuki
> */
> struct etmv4_caps {
> u8 nr_pe;
> @@ -907,6 +909,7 @@ struct etmv4_caps {
> bool atbtrig : 1;
> bool lpoverride : 1;
> bool skip_power_up : 1;
> + bool trcextout : 1;
> };
>
> /**
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> index 2b40e556be872..7b3800138f625 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> @@ -250,6 +250,9 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page)
> if (match_flags & CS_CFG_MATCH_CLASS_SRC_ETM4)
> used += scnprintf(page + used, PAGE_SIZE - used, "SRC_ETMV4 ");
>
> + if (match_flags & CS_CFG_MATCH_CAP_TRCEXTOUT)
> + used += scnprintf(page + used, PAGE_SIZE - used, "TRCEXTOUT ");
> +
> used += scnprintf(page + used, PAGE_SIZE - used, "\n");
> return used;
> }
This series depends on:
https://lore.kernel.org/linux-perf-users/20261030-perf_cs_etm_fix_non_taken…
Fix a few issues with per-thread mode:
- On nVHE, everything looks like guest trace instead of host
- Tracing multiple threads didn't really work
After adding a tests for those, it turns out there were some snapshot
bugs not picked up by the other snapshot tests. That showed that the
different snapshot searches for Intel BTS and Arm SPE were inconsistent
and I think all tracers can benefit from using the same pointer fixup
logic, so that gets refactored into the common auxtrace.c. Then SPE can
just share the Intel BTS search as it was obviously copied from it
originally. IntelPT keeps the more advanced duplicate data search, but
in the future that could probably be made the common one and all tracers
would benefit from using it (except maybe BTS if it always has a very
small buffer, but I doubt the overhead of the duplicate search would be
an issue). For now this is more of a refactor rather than behavioral
change so don't do that yet.
Signed-off-by: James Clark <james.clark(a)linaro.org>
---
Changes in v4:
- Change test snapshot size to 128K for 64K machines
- Put patchset depencency in cover letter text
- Link to v3: https://patch.msgid.link/20261102-james-cs-unformatted-per-thread-fix-v3-0-…
Changes in v3:
- Keep the find_snapshot() callback instead of adding
snapshot_has_wrapped() and monotonic_snapshot_head boolean (Adrian)
- Add auxtrace_record__default_find_snapshot() for the simple search for
BTS and SPE (Adrian)
- Add auxtrace_record__snapshot_fixup() for any snapshot search
implementation to use to update the pointers (Adrian)
- Reword UINT64_MAX timestamp comment (Leo)
- Fix disassembly test after rebasing onto exception sample fixes
- Only take 'perf_guest' into account if there is no PIDFMT_CTXTID2
- Improve decoding of old files by hard coding queue 0 for per-thread
- Link to v2: https://patch.msgid.link/20260821-james-cs-unformatted-per-thread-fix-v2-0-…
Changes in v2:
- Remove stale "may be reset to -1 in per-thread mode" comment
- Set CPU when queueing auxtrace fragments otherwise
auxtrace_queues__add_event() overwrites the queue's CPU
- Link to v1: https://patch.msgid.link/20260811-james-cs-unformatted-per-thread-fix-v1-0-…
---
James Clark (19):
perf cs-etm: Fix nVHE per-thread decoding
perf cs-etm: Warn for invalid timestamp option
perf cs-etm: Turn on context packet timestamps in per-thread mode
perf cs-etm: Use per-CPU queues for per-thread mode
perf test: cs-etm: Increase window size in disassembly test
perf cs-etm: Don't drop previous target for kernel samples
perf python: Expose sample instruction length
perf cs-etm: Use instruction length in disassembly script
perf cs-etm: Increase default timestamp generation period
perf auxtrace: Turn Intel BTS snapshot search into a generic one
perf arm-spe: Use generic snapshot search
perf auxtrace: intel-pt: Use common snapshot pointer fixup
perf cs-etm: Queue partial AUX records
perf cs-etm: Don't print missing buffers in snapshot mode
perf auxtrace: cs-etm: Capture wrapped snapshots
perf test: Allow infinite named_thread loops
perf test: cs-etm: Add test for per-thread mode
perf test: cs-etm: Test multiple per-thread threads
perf test: cs-etm: Increase snapshot size
tools/perf/Documentation/perf-test.txt | 2 +-
tools/perf/arch/arm/util/cs-etm.c | 34 ++++-
tools/perf/arch/arm64/util/arm-spe.c | 147 +--------------------
tools/perf/arch/x86/util/intel-bts.c | 115 +---------------
tools/perf/arch/x86/util/intel-pt.c | 21 +--
tools/perf/python/arm-cs-trace-disasm.py | 22 +--
tools/perf/python/perf.pyi | 1 +
.../perf/tests/shell/coresight/per-thread-multi.sh | 76 +++++++++++
tools/perf/tests/shell/coresight/per-thread.sh | 48 +++++++
.../perf/tests/shell/coresight/raw_dump_stress.sh | 5 -
.../shell/coresight/test_arm_coresight_disasm.sh | 8 +-
tools/perf/tests/workloads/named_threads.c | 7 +-
tools/perf/util/auxtrace.c | 145 +++++++++++++++++++-
tools/perf/util/auxtrace.h | 18 +++
tools/perf/util/cs-etm.c | 113 +++++++++++-----
tools/perf/util/python.c | 1 +
16 files changed, 420 insertions(+), 343 deletions(-)
---
base-commit: 28ef93607ad52acc8f8be25199711153ba11a0c2
change-id: 20260605-james-cs-unformatted-per-thread-fix-50e723aa7f0e
prerequisite-message-id: <20261030-perf_cs_etm_fix_non_taken-v3-0-7629b52ab047(a)arm.com>
prerequisite-patch-id: 4ef889ad751e344ae47c1d75a2a2e6cb2eadf6e1
prerequisite-patch-id: 636b39730334cbc5a76642c070e704ffe178e7be
prerequisite-patch-id: fb58f6daebdf5a194f8aa56ccc4022f932a5a6e5
prerequisite-patch-id: d240c10c6824f8ae6c3f10a1da01226a957f05fb
prerequisite-patch-id: 17b291db261e32dcb0d6f1ab2ed0adb7e0411813
prerequisite-patch-id: 45ae1d523c9e5c8c573309f1dab107a598f3d4f8
prerequisite-patch-id: 39a3eb25b3a45f4481760c25fa270773bcfd94f5
prerequisite-patch-id: 5723a15636c2a28ec40eb6b5c9836d162e971786
prerequisite-patch-id: d18054b586fc38bc832ead185e8c1fbb0ce46f39
prerequisite-patch-id: 6735b192189d7945613458abce3da871cb79b35d
prerequisite-patch-id: 387cb2c6181bef8f45a8fb167e8ef86e4a54ff69
prerequisite-patch-id: 50243a8d1739141aa24aa371a8452d4d2d078a99
prerequisite-patch-id: 2ae6f1e7707ba0c71a0678331b02d738fb25cb3c
prerequisite-patch-id: 1fa0a90cfbc904c4429c1427409125ac44b27aed
Best regards,
--
James Clark <james.clark(a)linaro.org>
On Sun, Oct 25, 2026 at 10:48:20PM -0700, Amir Ayupov wrote:
> Add an ETMv4 configuration, pmu_pulse, that drives trace unit external
> output 1 on every traced cycle, so a PMU event counting it (TRCEXTOUT1)
> can end a fixed-length ETM window, for example with aux-action=pause.
> The feature only loads on an ETE whose PMU counts its external outputs.
>
> Patch 1 is Leo's fix for TRCIDR0.NUMEVENT decoding, which patch 6 relies
> on for the number of external outputs.
Maybe it is worth to update patch 03 for Suzuki's comment:
https://lore.kernel.org/linux-arm-kernel/82adee03-a169-4106-99f2-7624a49260…
This series looks good to me and I have verified it:
Tested-by: Leo Yan <leo.yan(a)arm.com>