[RFC,2/2] arm_pmuv3: Add config bits for sample period strobing

Message ID 20240123113420.1928154-3-ben.gainey@arm.com
State New
Headers
Series A mechanism for efficient support for per-function metrics |

Commit Message

Ben Gainey Jan. 23, 2024, 11:34 a.m. UTC
  To expose the ability to alternate between sample periods to tools.
The field `strobe_period` is defined for config2 to hold the alternate
sample period. A non-zero value will enable strobing.

Signed-off-by: Ben Gainey <ben.gainey@arm.com>
---
 drivers/perf/arm_pmuv3.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
  

Patch

diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
index 23fa6c5da82c4..66b0219111bb8 100644
--- a/drivers/perf/arm_pmuv3.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -318,6 +318,9 @@  static const struct attribute_group armv8_pmuv3_events_attr_group = {
 #define ATTR_CFG_FLD_threshold_CFG		config1 /* PMEVTYPER.TH */
 #define ATTR_CFG_FLD_threshold_LO		5
 #define ATTR_CFG_FLD_threshold_HI		16
+#define ATTR_CFG_FLD_strobe_period_CFG		config2
+#define ATTR_CFG_FLD_strobe_period_LO		0
+#define ATTR_CFG_FLD_strobe_period_HI		31
 
 GEN_PMU_FORMAT_ATTR(event);
 GEN_PMU_FORMAT_ATTR(long);
@@ -325,6 +328,7 @@  GEN_PMU_FORMAT_ATTR(rdpmc);
 GEN_PMU_FORMAT_ATTR(threshold_count);
 GEN_PMU_FORMAT_ATTR(threshold_compare);
 GEN_PMU_FORMAT_ATTR(threshold);
+GEN_PMU_FORMAT_ATTR(strobe_period);
 
 static int sysctl_perf_user_access __read_mostly;
 
@@ -352,6 +356,16 @@  static u8 armv8pmu_event_threshold_control(struct perf_event_attr *attr)
 	return (th_compare << 1) | th_count;
 }
 
+static inline u32 armv8pmu_event_strobe_period(struct perf_event *event)
+{
+	return ATTR_CFG_GET_FLD(&event->attr, strobe_period);
+}
+
+static inline bool armv8pmu_event_want_strobe(struct perf_event *event)
+{
+	return armv8pmu_event_strobe_period(event) != 0;
+}
+
 static struct attribute *armv8_pmuv3_format_attrs[] = {
 	&format_attr_event.attr,
 	&format_attr_long.attr,
@@ -359,6 +373,7 @@  static struct attribute *armv8_pmuv3_format_attrs[] = {
 	&format_attr_threshold.attr,
 	&format_attr_threshold_compare.attr,
 	&format_attr_threshold_count.attr,
+	&format_attr_strobe_period.attr,
 	NULL,
 };
 
@@ -1125,6 +1140,16 @@  static int __armv8_pmuv3_map_event(struct perf_event *event,
 	if (armv8pmu_event_is_64bit(event))
 		event->hw.flags |= ARMPMU_EVT_64BIT;
 
+	/*
+	 * Support alternating between two sample periods
+	 */
+	if (armv8pmu_event_want_strobe(event)) {
+		u32 strobe_period = armv8pmu_event_strobe_period(event);
+		armpmu_set_strobe_period(&(event->hw), strobe_period);
+	} else {
+		armpmu_set_strobe_period(&(event->hw), 0);
+	}
+
 	/*
 	 * User events must be allocated into a single counter, and so
 	 * must not be chained.