mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event
@ 2026-10-12 23:05 Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw)
  To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin
  Cc: Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier,
	Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc,
	linux-kernel

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 ETMs whose PMU counts that output.

Changes in v2:
- Split the -EINVAL fix for a configuration that is active but not loaded
  on the device into its own patch, with a Fixes tag and an early return
  (Leo).
- Match capability flags separately from the device class: a feature
  loads on a device that shares one of its classes and has all of its
  capabilities, checked once in cscfg_load_feat_csdev() (Leo).
- Report each external output the PMU counts, TRCEXTOUT0-3, instead of
  only output 1 (Leo).
- Detect the outputs from TRCIDR0.NUMEVENT and PMCEID0_EL0, and drop the
  MIDR list (Leo, James).
- extout_pulse requires CS_CFG_MATCH_CLASS_SRC_ETM4 and
  CS_CFG_MATCH_CAP_PMU_EXTOUT(1). It still uses event and output 1:
  event 0 is the trace unit trigger, which the TRBE driver treats as
  fatal (James).
- Link to v1: https://lore.kernel.org/r/20261001063744.2143819-1-aaupov@fb.com

Tested on Grace/Neoverse V2, pmu_pulse config loaded successfully.


Amir Ayupov (4):
  coresight: syscfg: Fail to enable a configuration not loaded on the
    device
  coresight: syscfg: Match feature capabilities separately from device
    class
  coresight: etm4x: Report the external outputs the PMU counts
  coresight: Add pmu_pulse/extout_pulse

 .../trace/coresight/coresight-config.rst      |  5 ++
 .../trace/coresight/coresight-perf.rst        | 19 ++++
 drivers/hwtracing/coresight/Makefile          |  1 +
 .../coresight/coresight-cfg-pmu-pulse.c       | 55 ++++++++++++
 .../coresight/coresight-cfg-preload.c         |  2 +
 .../coresight/coresight-cfg-preload.h         |  2 +
 .../hwtracing/coresight/coresight-config.h    | 10 +++
 .../hwtracing/coresight/coresight-etm4x-cfg.c |  5 +-
 .../coresight/coresight-etm4x-core.c          | 32 +++++++
 drivers/hwtracing/coresight/coresight-etm4x.h |  3 +
 .../coresight/coresight-syscfg-configfs.c     |  7 ++
 .../hwtracing/coresight/coresight-syscfg.c    | 88 +++++++++++--------
 12 files changed, 193 insertions(+), 36 deletions(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c


base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
-- 
2.52.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device
  2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov
@ 2026-10-12 23:05 ` Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw)
  To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin
  Cc: Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier,
	Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc,
	linux-kernel

cscfg_csdev_enable_active_config() looks up the selected configuration in
the device's loaded configurations, and returns success when it is not
there. A configuration is only loaded on devices that match at least one
of its features, so a perf session or sysfs enable that selects it on any
other device runs without the configuration, with no error.

Return -EINVAL instead, so enabling the source fails on that device. The
function is only called with a non-zero configuration hash, so sources
enabled without a configuration are unaffected.

Fixes: f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enable configurations")
Assisted-by: Devmate:Opus-5.5
Signed-off-by: Amir Ayupov <aaupov@fb.com>
---
 .../hwtracing/coresight/coresight-syscfg.c    | 53 ++++++++++---------
 1 file changed, 28 insertions(+), 25 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 2bfdd7b45e49c..a816c22c87bc8 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -1088,36 +1088,39 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
 	raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 
 	/*
-	 * If found, attempt to enable
+	 * The configuration is active but not loaded on this device, because
+	 * none of its features match the device. Fail rather than trace
+	 * without it.
 	 */
-	if (config_csdev_active) {
+	if (!config_csdev_active)
+		return -EINVAL;
+
+	/*
+	 * Call the generic routine that will program up the internal
+	 * driver structures prior to programming up the hardware.
+	 * This routine takes the driver spinlock saved in the configs.
+	 */
+	err = cscfg_csdev_enable_config(config_csdev_active, preset);
+	if (!err) {
 		/*
-		 * Call the generic routine that will program up the internal
-		 * driver structures prior to programming up the hardware.
-		 * This routine takes the driver spinlock saved in the configs.
+		 * Successful programming. Check the active_cscfg_ctxt
+		 * pointer to ensure no pre-emption disabled it via
+		 * cscfg_csdev_disable_active_config() before
+		 * we could start.
+		 *
+		 * Set enabled if OK, err if not.
 		 */
-		err = cscfg_csdev_enable_config(config_csdev_active, preset);
-		if (!err) {
-			/*
-			 * Successful programming. Check the active_cscfg_ctxt
-			 * pointer to ensure no pre-emption disabled it via
-			 * cscfg_csdev_disable_active_config() before
-			 * we could start.
-			 *
-			 * Set enabled if OK, err if not.
-			 */
-			raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
-			if (csdev->active_cscfg_ctxt)
-				config_csdev_active->enabled = true;
-			else
-				err = -EBUSY;
-			raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
-		}
-
-		if (err)
-			cscfg_config_desc_put(config_desc);
+		raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+		if (csdev->active_cscfg_ctxt)
+			config_csdev_active->enabled = true;
+		else
+			err = -EBUSY;
+		raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
 	}
 
+	if (err)
+		cscfg_config_desc_put(config_desc);
+
 	return err;
 }
 EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
-- 
2.52.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class
  2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov
@ 2026-10-12 23:05 ` Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov
  3 siblings, 0 replies; 6+ messages in thread
From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw)
  To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin
  Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight,
	linux-arm-kernel, linux-doc, linux-kernel

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.

Reserve CS_CFG_MATCH_CAP_MASK for capability flags. A feature now loads on
a device that shares one of its other flags 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@fb.com>
---
 .../hwtracing/coresight/coresight-config.h    |  6 ++++
 .../hwtracing/coresight/coresight-syscfg.c    | 35 +++++++++++++------
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 90fd937d3bd83..af6ef96b9ae01 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -30,6 +30,12 @@
 #define CS_CFG_MATCH_CLASS_SRC_ALL	0x0001	/* match any source */
 #define CS_CFG_MATCH_CLASS_SRC_ETM4	0x0002	/* match any ETMv4 device */
 
+/*
+ * 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		0x0000ff00
+
 /* 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..1545d64afec01 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc
 }
 
 /* load one feature into one coresight device */
+/*
+ * A feature matches a device that shares one of its class flags and has all of
+ * the capability flags it requires.
+ */
+static bool cscfg_match_feat_csdev(u32 feat_flags, u32 csdev_flags)
+{
+	u32 caps = feat_flags & CS_CFG_MATCH_CAP_MASK;
+
+	return (feat_flags & csdev_flags & ~CS_CFG_MATCH_CAP_MASK) &&
+	       (csdev_flags & caps) == caps;
+}
+
+/* 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;
 }
-- 
2.52.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
  2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov
@ 2026-10-12 23:05 ` Amir Ayupov
  2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov
  3 siblings, 0 replies; 6+ messages in thread
From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw)
  To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin
  Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight,
	linux-arm-kernel, linux-doc, linux-kernel

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, which outputs the PMU counts:
the trace unit has an external output for each of its events
(TRCIDR0.NUMEVENT), and from PMUv3p1, PMCEID0_EL0[63:32] reports which of
the common events 0x4000-0x401f are implemented. Per the ETE
specification, an implemented TRCEXTOUTn event counts external output n;
only whether that output is also an external input is IMPLEMENTATION
DEFINED.

Add a capability match flag for each output,
CS_CFG_MATCH_CAP_PMU_EXTOUT(n), set it on ETMs whose PMU counts that
output, and show it in the feature's configfs 'matches' attribute. With
capabilities matched separately from the device class, a feature that
requires one only loads on those ETMs.

Assisted-by: Devmate:Opus-5.5
Signed-off-by: Amir Ayupov <aaupov@fb.com>
---
 .../hwtracing/coresight/coresight-config.h    |  4 +++
 .../hwtracing/coresight/coresight-etm4x-cfg.c |  5 ++-
 .../coresight/coresight-etm4x-core.c          | 32 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-etm4x.h |  3 ++
 .../coresight/coresight-syscfg-configfs.c     |  7 ++++
 5 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index af6ef96b9ae01..10e95f5ecc8d9 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -35,6 +35,10 @@
  * a device that matches one of its classes and has all of its capabilities.
  */
 #define CS_CFG_MATCH_CAP_MASK		0x0000ff00
+/* trace unit external output n is countable by the PMU as TRCEXTOUTn */
+#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT	8
+#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR	4	/* TRCEXTOUT0-3 */
+#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n)	BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n))
 
 /* 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-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
index e1a59b4345052..09a7a6b86968c 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
@@ -174,9 +174,12 @@ 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;
+	match_flags |= (u32)drvdata->pmu_extout << CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT;
 
-	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 2247ad55d4442..1e78774025d13 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>
@@ -1368,6 +1369,35 @@ static void etm4_fixup_wrong_ccitmin(struct etmv4_drvdata *drvdata)
 	}
 }
 
+/*
+ * Find the external outputs of this trace unit that the PMU counts as the
+ * common events TRCEXTOUT0-3. The trace unit has an external output for each
+ * of its events, and PMCEID0_EL0[63:32] reports the common events
+ * 0x4000-0x401f from PMUv3p1.
+ *
+ * Must run on the CPU that owns the trace unit.
+ */
+static u8 etm4_pmu_extout(struct etmv4_drvdata *drvdata)
+{
+	int pmuver = read_pmuver();
+	u64 pmceid;
+	u8 extout = 0;
+	int n;
+
+	if (!pmuv3_implemented(pmuver) || pmuver < ID_AA64DFR0_EL1_PMUVer_V3P1)
+		return 0;
+
+	pmceid = read_pmceid0() >> 32;
+	/* nr_event is TRCIDR0.NUMEVENT, the number of events minus one */
+	for (n = 0; n <= drvdata->nr_event; n++) {
+		if (pmceid & BIT_ULL(ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 + n -
+				     ARMV8_PMUV3_EXT_COMMON_EVENT_BASE))
+			extout |= BIT(n);
+	}
+
+	return extout;
+}
+
 static void etm4_init_arch_data(void *info)
 {
 	u32 etmidr0;
@@ -1522,6 +1552,8 @@ static void etm4_init_arch_data(void *info)
 	/* NUMCNTR, bits[30:28] number of counters available for tracing */
 	drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
 
+	drvdata->pmu_extout = etm4_pmu_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 df9e0748d71ec..11d95a4518b88 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -979,6 +979,8 @@ struct etmv4_save_state {
  * @nrseqstate: The number of sequencer states that are implemented.
  * @nr_seq_ctrls: The number of sequence state transition control registers.
  * @nr_event:	Indicates how many events the trace unit support.
+ * @pmu_extout:	Bitmap of the external outputs n that the PMU counts as
+ *		TRCEXTOUTn.
  * @nr_resource:The number of resource selection pairs available for tracing.
  * @nr_ss_cmp:	Number of single-shot comparator controls that are available.
  * @trcid:	value of the current ID for this component.
@@ -1045,6 +1047,7 @@ struct etmv4_drvdata {
 	u8				nrseqstate;
 	u8				nr_seq_ctrls;
 	u8				nr_event;
+	u8				pmu_extout;
 	u8				nr_resource;
 	u8				nr_ss_cmp;
 	u8				trcid;
diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
index 2b40e556be872..7893d40f2e9ea 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
@@ -243,6 +243,7 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page)
 							struct cscfg_fs_feature, group);
 	u32 match_flags = fs_feat->feat_desc->match_flags;
 	int used = 0;
+	int n;
 
 	if (match_flags & CS_CFG_MATCH_CLASS_SRC_ALL)
 		used = scnprintf(page, PAGE_SIZE, "SRC_ALL ");
@@ -250,6 +251,12 @@ 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 ");
 
+	for (n = 0; n < CS_CFG_MATCH_CAP_PMU_EXTOUT_NR; n++) {
+		if (match_flags & CS_CFG_MATCH_CAP_PMU_EXTOUT(n))
+			used += scnprintf(page + used, PAGE_SIZE - used,
+					  "PMU_EXTOUT%d ", n);
+	}
+
 	used += scnprintf(page + used, PAGE_SIZE - used, "\n");
 	return used;
 }
-- 
2.52.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse
  2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov
                   ` (2 preceding siblings ...)
  2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov
@ 2026-10-12 23:05 ` Amir Ayupov
  2026-10-13  1:09   ` Daniel Pereira
  3 siblings, 1 reply; 6+ messages in thread
From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw)
  To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin
  Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight,
	linux-arm-kernel, linux-doc, linux-kernel

Add ETMv4 configuration 'pmu_pulse' with 'extout_pulse' feature which
requires an ETM whose PMU counts external output 1
(CS_CFG_MATCH_CAP_PMU_EXTOUT(1)): event 1 selects the always-true
resource and drives TRCEXTOUT1 PMU event which pulses on every cycle
while the trace unit is enabled.

The intended use is for CSSPGO profiling: a fixed-length ETM strobing
window that ends at a PMU event. The window is decoded into branch
stack, PMU event is carrying callchains. pmu_pulse allows specifying the
window in ETM cycles.

Assisted-by: Devmate:Opus-5.5
Signed-off-by: Amir Ayupov <aaupov@fb.com>
---
 .../trace/coresight/coresight-config.rst      |  5 ++
 .../trace/coresight/coresight-perf.rst        | 19 +++++++
 drivers/hwtracing/coresight/Makefile          |  1 +
 .../coresight/coresight-cfg-pmu-pulse.c       | 55 +++++++++++++++++++
 .../coresight/coresight-cfg-preload.c         |  2 +
 .../coresight/coresight-cfg-preload.h         |  2 +
 6 files changed, 84 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c

diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst
index 6d5ffa6f73471..3eed728bf0de1 100644
--- a/Documentation/trace/coresight/coresight-config.rst
+++ b/Documentation/trace/coresight/coresight-config.rst
@@ -129,6 +129,11 @@ The following steps take place in the operation of a configuration.
 
 5) At the end of the perf session, the configuration will be disabled.
 
+The built-in 'pmu_pulse' configuration pulses ETM external output 1 for a PMU
+event to count. It only pulses while the ETM is enabled, so combined with AUX
+pause and resume the PMU event can time each trace window (see
+coresight-perf.rst).
+
 
 Viewing Configurations and Features
 ===================================
diff --git a/Documentation/trace/coresight/coresight-perf.rst b/Documentation/trace/coresight/coresight-perf.rst
index 0a77741a431ef..7163d206f9b36 100644
--- a/Documentation/trace/coresight/coresight-perf.rst
+++ b/Documentation/trace/coresight/coresight-perf.rst
@@ -109,6 +109,25 @@ Example for triggering AUX pause and resume with PMU event::
         -e cycles/aux-action=pause,period=10000000/ \
         -e cycles/aux-action=resume,period=1050000/ -- sleep 1
 
+ETM-timed pause events
+~~~~~~~~~~~~~~~~~~~~~~
+
+The built-in ``pmu_pulse`` configuration pulses ETM external output 1 on every
+cycle of allowed trace, and a PMU event counting that output pauses trace after
+``N`` pulses, here 1000 cycles::
+
+  perf record -T \
+    -e cs_etm/pmu_pulse,aux-action=start-paused,timestamp/u \
+    -e armv8_pmuv3_0/cpu_cycles,aux-action=resume,period=1050031/u \
+    -e armv8_pmuv3_0/trcextout1,aux-action=pause,period=1000,call-graph=fp/u \
+    -- ./workload
+
+Each window is about ``N`` traced cycles plus the pause interrupt latency, so
+windows are never empty and a callchain on the pause event is taken where
+trace ends. The configuration only loads where the PMU counts ETM external
+output 1, which the feature's configfs 'matches' attribute shows as
+PMU_EXTOUT1; elsewhere a session selecting it fails to start.
+
 Perf test - Verify kernel and userspace perf CoreSight work
 -----------------------------------------------------------
 
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index ab16d06783a57..568e797ac5a17 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
 		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
 		coresight-cfg-preload.o coresight-cfg-afdo.o coresight-cfg-pstop.o \
+		coresight-cfg-pmu-pulse.o \
 		coresight-syscfg-configfs.o coresight-trace-id.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
diff --git a/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c b/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c
new file mode 100644
index 0000000000000..3772e5bd6cccf
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pulse ETM external output 1 on every traced cycle for a PMU event to count.
+ * Based on coresight-cfg-afdo.c
+ */
+
+#include "coresight-config.h"
+
+/* ETMv4 includes and features */
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
+#include "coresight-etm4x-cfg.h"
+
+/*
+ * extout_pulse feature: event 1 selects the always-true resource, so ETM
+ * external output 1 pulses on every cycle while the trace unit is enabled. A
+ * PMU event counting that output (TRCEXTOUT1), for example with
+ * aux-action=pause, then fires after as many traced cycles as its sample
+ * period. Event 0 is avoided because it is the trace unit trigger, and the
+ * TRBE driver treats a detected trigger as fatal.
+ */
+static struct cscfg_regval_desc extout_pulse_regs[] = {
+	/* event 1: resource selector 1 (always true), drives external output 1 */
+	{
+		.type = CS_CFG_REG_TYPE_STD | CS_CFG_REG_TYPE_VAL_MASK,
+		.offset = TRCEVENTCTL0R,
+		.val32 = 0x0100,
+		.mask32 = 0xff00,
+	},
+	/* end of regs */
+};
+
+struct cscfg_feature_desc extout_pulse_etm4x = {
+	.name = "extout_pulse",
+	.description = "Pulse external output 1 on every traced cycle.\n",
+	.match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4 | CS_CFG_MATCH_CAP_PMU_EXTOUT(1),
+	.nr_regs = ARRAY_SIZE(extout_pulse_regs),
+	.regs_desc = extout_pulse_regs,
+};
+
+/* create a pmu_pulse configuration */
+
+static const char *pmu_pulse_ref_names[] = {
+	"extout_pulse",
+};
+
+struct cscfg_config_desc pmu_pulse_etm4x = {
+	.name = "pmu_pulse",
+	.description = "Pulse ETM external output 1 on every traced cycle for the PMU\n"
+	"to count as TRCEXTOUT1\n",
+	.nr_feat_refs = ARRAY_SIZE(pmu_pulse_ref_names),
+	.feat_ref_names = pmu_pulse_ref_names,
+};
+
+/* end of ETM4x configurations */
+#endif	/* IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) */
diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c
index 4980e68483c5b..a9a60a1c40845 100644
--- a/drivers/hwtracing/coresight/coresight-cfg-preload.c
+++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c
@@ -14,6 +14,7 @@ static struct cscfg_feature_desc *preload_feats[] = {
 #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
 	&strobe_etm4x,
 	&gen_etrig_etm4x,
+	&extout_pulse_etm4x,
 #endif
 	NULL
 };
@@ -22,6 +23,7 @@ static struct cscfg_config_desc *preload_cfgs[] = {
 #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
 	&afdo_etm4x,
 	&pstop_etm4x,
+	&pmu_pulse_etm4x,
 #endif
 	NULL
 };
diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.h b/drivers/hwtracing/coresight/coresight-cfg-preload.h
index 291ba530a6a52..0058627f65ae5 100644
--- a/drivers/hwtracing/coresight/coresight-cfg-preload.h
+++ b/drivers/hwtracing/coresight/coresight-cfg-preload.h
@@ -12,4 +12,6 @@ extern struct cscfg_feature_desc strobe_etm4x;
 extern struct cscfg_config_desc afdo_etm4x;
 extern struct cscfg_feature_desc gen_etrig_etm4x;
 extern struct cscfg_config_desc pstop_etm4x;
+extern struct cscfg_feature_desc extout_pulse_etm4x;
+extern struct cscfg_config_desc pmu_pulse_etm4x;
 #endif
-- 
2.52.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse
  2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov
@ 2026-10-13  1:09   ` Daniel Pereira
  0 siblings, 0 replies; 6+ messages in thread
From: Daniel Pereira @ 2026-10-13  1:09 UTC (permalink / raw)
  To: Amir Ayupov
  Cc: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach,
	Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan,
	coresight, linux-arm-kernel, linux-doc, linux-kernel

On Mon, Oct 12, 2026 at 04:05:23PM -0700, Amir Ayupov wrote:
[...]
> +  perf record -T \
> +    -e cs_etm/pmu_pulse,aux-action=start-paused,timestamp/u \
> +    -e armv8_pmuv3_0/cpu_cycles,aux-action=resume,period=1050031/u \
> +    -e armv8_pmuv3_0/trcextout1,aux-action=pause,period=1000,call-graph=fp/u \
> +    -- ./workload

The CPU PMU name depends on the system: armv8_pmuv3_0 is what ACPI
systems get, while on devicetree systems it comes from the compatible
string, e.g. armv8_pmuv3 or armv8_cortex_a76. Maybe add a sentence
after the example, along the lines of:

  The CPU PMU name depends on the system; the available PMUs are
  listed under /sys/bus/event_source/devices/.

I applied the documentation hunks and built htmldocs, no new warnings.
With or without the above, for the documentation part:

Reviewed-by: Daniel Pereira <danielmaraboo@gmail.com>

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-10-13  1:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov
2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov
2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov
2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov
2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov
2026-10-13  1:09   ` Daniel Pereira

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®