linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] perf: Clean up common uncore boilerplate
@ 2024-03-12 17:34 Robin Murphy
  2024-03-12 17:34 ` [PATCH 01/10] perf/alibaba_uncore_drw: Use correct CPU affinity Robin Murphy
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

Hi all,

Since this came up yet again recently, and it's an idea which has been
nagging me for years, I decided it was time to see how hard it really
would be to start shaving this yak. And it turns out to be refreshingly
simple - the core code has quietly become capable of doing most of what
we want, the one new functional addition is trivial (patch #2), and the
resulting largely-mechanical cleanup seems a pretty nice win.

This series is focused on drivers/perf/ as that's where most mess is
concentrated, but figured I'd include the arch/ patches as well since
they might be reasonable to land with the core changes, at least for x86
(FWIW I did also look at the powerpc drivers but they scared me and I
ran away; sorry). The remaining stragglers elsewhere around the tree I'd
come back to as a follow-up.

(And yes, I appreciate it's mid-merge-window already, but since I do
have a tree-wide rename proposed here, may as well give the discussion
a chance for a head start before -rc1...)

Thanks,
Robin.


Robin Murphy (10):
  perf/alibaba_uncore_drw: Use correct CPU affinity
  perf: Add capability for common event support
  drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS
  perf: Rename PERF_PMU_CAP_NO_INTERRUPT
  drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently
  drivers/perf: Clean up redundant per-task checks
  perf: Define common uncore capabilities
  drivers/perf: Use common uncore capabilities
  x86: Use common uncore PMU capabilities
  ARM: Use common uncore PMU capabilities

 arch/arc/kernel/perf_event.c              |  2 +-
 arch/arm/mach-imx/mmdc.c                  | 16 +-------------
 arch/arm/mm/cache-l2x0-pmu.c              | 12 +---------
 arch/csky/kernel/perf_event.c             |  2 +-
 arch/powerpc/perf/8xx-pmu.c               |  2 +-
 arch/powerpc/perf/hv-24x7.c               |  2 +-
 arch/powerpc/perf/hv-gpci.c               |  2 +-
 arch/powerpc/platforms/pseries/papr_scm.c |  2 +-
 arch/s390/kernel/perf_cpum_cf.c           |  2 +-
 arch/sh/kernel/perf_event.c               |  2 +-
 arch/x86/events/amd/iommu.c               | 17 +-------------
 arch/x86/events/amd/power.c               | 10 +--------
 arch/x86/events/amd/uncore.c              | 12 +++-------
 arch/x86/events/core.c                    |  2 +-
 arch/x86/events/intel/cstate.c            | 16 +++-----------
 arch/x86/events/intel/uncore.c            | 11 +--------
 arch/x86/events/intel/uncore_snb.c        | 20 +++--------------
 arch/x86/events/msr.c                     |  9 +-------
 arch/x86/events/rapl.c                    |  9 +-------
 drivers/fpga/dfl-fme-perf.c               |  2 +-
 drivers/perf/alibaba_uncore_drw_pmu.c     | 27 +++--------------------
 drivers/perf/amlogic/meson_ddr_pmu_core.c | 11 +--------
 drivers/perf/arm-cci.c                    | 15 +------------
 drivers/perf/arm-ccn.c                    | 20 +----------------
 drivers/perf/arm-cmn.c                    | 10 +--------
 drivers/perf/arm_cspmu/arm_cspmu.c        | 27 ++---------------------
 drivers/perf/arm_dmc620_pmu.c             | 18 +--------------
 drivers/perf/arm_dsu_pmu.c                | 22 +-----------------
 drivers/perf/arm_pmu_platform.c           |  2 +-
 drivers/perf/arm_smmuv3_pmu.c             | 15 +------------
 drivers/perf/arm_spe_pmu.c                |  7 ++----
 drivers/perf/cxl_pmu.c                    |  8 +------
 drivers/perf/dwc_pcie_pmu.c               | 13 +----------
 drivers/perf/fsl_imx8_ddr_perf.c          | 13 +----------
 drivers/perf/fsl_imx9_ddr_perf.c          | 13 +----------
 drivers/perf/hisilicon/hisi_pcie_pmu.c    | 10 +--------
 drivers/perf/hisilicon/hisi_uncore_pmu.c  | 20 +----------------
 drivers/perf/hisilicon/hns3_pmu.c         |  9 +-------
 drivers/perf/marvell_cn10k_ddr_pmu.c      | 15 +------------
 drivers/perf/marvell_cn10k_tad_pmu.c      |  6 +----
 drivers/perf/qcom_l2_pmu.c                | 21 ++----------------
 drivers/perf/qcom_l3_pmu.c                | 21 +-----------------
 drivers/perf/riscv_pmu_sbi.c              |  2 +-
 drivers/perf/thunderx2_pmu.c              | 17 +-------------
 drivers/perf/xgene_pmu.c                  | 16 +-------------
 include/linux/perf_event.h                |  6 ++++-
 kernel/events/core.c                      |  7 +++++-
 47 files changed, 67 insertions(+), 456 deletions(-)

-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 01/10] perf/alibaba_uncore_drw: Use correct CPU affinity
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-12 17:34 ` [PATCH 02/10] perf: Add capability for common event support Robin Murphy
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Shuai Xue

Although this driver is trying to use the IRQ-multiplexing mechanism to
handle context migration correctly, it's failing to make events follow
the IRQ instance, instead forcing them onto a per-PMU CPU which is set
once at probe time then never maintained. Fix this by using the correct
CPU from the IRQ instance, and remove the erroneous per-PMU data plus
the redundant check which does not mean what it thinks it means.

CC: Shuai Xue <xueshuai@linux.alibaba.com>
Fixes: cf7b61073e45 ("drivers/perf: add DDR Sub-System Driveway PMU driver for Yitian 710 SoC")
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/alibaba_uncore_drw_pmu.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
index 19d459a36be5..b37e9794823a 100644
--- a/drivers/perf/alibaba_uncore_drw_pmu.c
+++ b/drivers/perf/alibaba_uncore_drw_pmu.c
@@ -96,8 +96,6 @@ struct ali_drw_pmu {
 
 	struct list_head pmus_node;
 	struct ali_drw_pmu_irq *irq;
-	int irq_num;
-	int cpu;
 	DECLARE_BITMAP(used_mask, ALI_DRW_PMU_COMMON_MAX_COUNTERS);
 	struct perf_event *events[ALI_DRW_PMU_COMMON_MAX_COUNTERS];
 	int evtids[ALI_DRW_PMU_COMMON_MAX_COUNTERS];
@@ -221,7 +219,7 @@ static ssize_t ali_drw_pmu_cpumask_show(struct device *dev,
 {
 	struct ali_drw_pmu *drw_pmu = to_ali_drw_pmu(dev_get_drvdata(dev));
 
-	return cpumap_print_to_pagebuf(true, buf, cpumask_of(drw_pmu->cpu));
+	return cpumap_print_to_pagebuf(true, buf, cpumask_of(drw_pmu->irq->cpu));
 }
 
 static struct device_attribute ali_drw_pmu_cpumask_attr =
@@ -550,11 +548,7 @@ static int ali_drw_pmu_event_init(struct perf_event *event)
 		return -EOPNOTSUPP;
 	}
 
-	event->cpu = drw_pmu->cpu;
-	if (event->cpu < 0) {
-		dev_err(dev, "Per-task mode not supported!\n");
-		return -EOPNOTSUPP;
-	}
+	event->cpu = drw_pmu->irq->cpu;
 
 	if (event->group_leader != event &&
 	    !is_software_event(event->group_leader)) {
@@ -701,8 +695,6 @@ static int ali_drw_pmu_probe(struct platform_device *pdev)
 	/* clearing interrupt status */
 	writel(0xffffff, drw_pmu->cfg_base + ALI_DRW_PMU_OV_INTR_CLR);
 
-	drw_pmu->cpu = smp_processor_id();
-
 	ret = ali_drw_pmu_init_irq(drw_pmu, pdev);
 	if (ret)
 		return ret;
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 02/10] perf: Add capability for common event support
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
  2024-03-12 17:34 ` [PATCH 01/10] perf/alibaba_uncore_drw: Use correct CPU affinity Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-14  8:09   ` Yang Jialong 杨佳龙
  2024-03-12 17:34 ` [PATCH 03/10] drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS Robin Murphy
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

Many PMUs do not support common hardware/cache/etc. events and only
handle their own PMU-specific events. Since this only depends on
matching the event and PMU types, it's a prime candidate for a core
capability to save more event_init boilerplate in drivers.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 include/linux/perf_event.h | 1 +
 kernel/events/core.c       | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d2a15c0c6f8a..983201f21dd2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -291,6 +291,7 @@ struct perf_event_pmu_context;
 #define PERF_PMU_CAP_NO_EXCLUDE			0x0040
 #define PERF_PMU_CAP_AUX_OUTPUT			0x0080
 #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
+#define PERF_PMU_CAP_NO_COMMON_EVENTS		0x0200
 
 struct perf_output_handle;
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f0f0f71213a1..7ad80826c218 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -11649,6 +11649,11 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
 	struct perf_event_context *ctx = NULL;
 	int ret;
 
+	/* Short-circuit if we know the PMU won't want this event */
+	if (pmu->capabilities & PERF_PMU_CAP_NO_COMMON_EVENTS &&
+	    event->attr.type != pmu->type)
+		return -ENOENT;
+
 	if (!try_module_get(pmu->module))
 		return -ENODEV;
 
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 03/10] drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
  2024-03-12 17:34 ` [PATCH 01/10] perf/alibaba_uncore_drw: Use correct CPU affinity Robin Murphy
  2024-03-12 17:34 ` [PATCH 02/10] perf: Add capability for common event support Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-12 17:34 ` [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT Robin Murphy
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

Now that we have a core capability for refusing common event types, make
use of it to purge the -ENOENT boilerplate from our system PMU drivers.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/alibaba_uncore_drw_pmu.c     |  6 ++----
 drivers/perf/amlogic/meson_ddr_pmu_core.c |  6 ++----
 drivers/perf/arm-cci.c                    | 10 ++--------
 drivers/perf/arm-ccn.c                    |  6 ++----
 drivers/perf/arm-cmn.c                    |  6 ++----
 drivers/perf/arm_cspmu/arm_cspmu.c        |  6 ++----
 drivers/perf/arm_dmc620_pmu.c             |  6 ++----
 drivers/perf/arm_dsu_pmu.c                |  6 ++----
 drivers/perf/arm_smmuv3_pmu.c             |  6 ++----
 drivers/perf/arm_spe_pmu.c                |  7 ++-----
 drivers/perf/cxl_pmu.c                    |  7 ++-----
 drivers/perf/dwc_pcie_pmu.c               |  6 ++----
 drivers/perf/fsl_imx8_ddr_perf.c          |  6 ++----
 drivers/perf/fsl_imx9_ddr_perf.c          |  6 ++----
 drivers/perf/hisilicon/hisi_pcie_pmu.c    |  7 ++-----
 drivers/perf/hisilicon/hisi_uncore_pmu.c  |  6 ++----
 drivers/perf/hisilicon/hns3_pmu.c         |  6 ++----
 drivers/perf/marvell_cn10k_ddr_pmu.c      |  6 ++----
 drivers/perf/marvell_cn10k_tad_pmu.c      |  6 ++----
 drivers/perf/qcom_l2_pmu.c                | 10 +++-------
 drivers/perf/qcom_l3_pmu.c                |  9 ++-------
 drivers/perf/thunderx2_pmu.c              |  7 ++-----
 drivers/perf/xgene_pmu.c                  |  7 ++-----
 23 files changed, 47 insertions(+), 107 deletions(-)

diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
index b37e9794823a..606c2301bd11 100644
--- a/drivers/perf/alibaba_uncore_drw_pmu.c
+++ b/drivers/perf/alibaba_uncore_drw_pmu.c
@@ -535,9 +535,6 @@ static int ali_drw_pmu_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	struct device *dev = drw_pmu->pmu.dev;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event)) {
 		dev_err(dev, "Sampling not supported!\n");
 		return -EOPNOTSUPP;
@@ -709,7 +706,8 @@ static int ali_drw_pmu_probe(struct platform_device *pdev)
 		.stop		= ali_drw_pmu_stop,
 		.read		= ali_drw_pmu_read,
 		.attr_groups	= ali_drw_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	ret = perf_pmu_register(&drw_pmu->pmu, name, -1);
diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
index bbc7285fd934..c19b682297f3 100644
--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
+++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
@@ -121,9 +121,6 @@ static int meson_ddr_perf_event_init(struct perf_event *event)
 	u64 config1 = event->attr.config1;
 	u64 config2 = event->attr.config2;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
@@ -492,7 +489,8 @@ int meson_ddr_pmu_create(struct platform_device *pdev)
 	*pmu = (struct ddr_pmu) {
 		.pmu = {
 			.module		= THIS_MODULE,
-			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+					  PERF_PMU_CAP_NO_COMMON_EVENTS,
 			.task_ctx_nr	= perf_invalid_context,
 			.attr_groups	= attr_groups,
 			.event_init	= meson_ddr_perf_event_init,
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 61de861eaf91..f157bfd4b923 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -815,10 +815,6 @@ static int pmu_map_event(struct perf_event *event)
 {
 	struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu);
 
-	if (event->attr.type < PERF_TYPE_MAX ||
-			!cci_pmu->model->validate_hw_event)
-		return -ENOENT;
-
 	return	cci_pmu->model->validate_hw_event(cci_pmu, event->attr.config);
 }
 
@@ -1316,9 +1312,6 @@ static int cci_pmu_event_init(struct perf_event *event)
 	atomic_t *active_events = &cci_pmu->active_events;
 	int err = 0;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/* Shared by all CPUs, no meaningful state to sample */
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
@@ -1420,7 +1413,8 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
 		.stop		= cci_pmu_stop,
 		.read		= pmu_read,
 		.attr_groups	= pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	cci_pmu->plat_device = pdev;
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 728d13d8e98a..ce26bb773a56 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -719,9 +719,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
 	int i;
 	struct perf_event *sibling;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	ccn = pmu_to_arm_ccn(event->pmu);
 
 	if (hw->sample_period) {
@@ -1275,7 +1272,8 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
 		.read = arm_ccn_pmu_event_read,
 		.pmu_enable = arm_ccn_pmu_enable,
 		.pmu_disable = arm_ccn_pmu_disable,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	/* No overflow interrupt? Have to use a timer instead. */
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index c584165b13ba..717dd90417d6 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -1696,9 +1696,6 @@ static int arm_cmn_event_init(struct perf_event *event)
 	bool bynodeid;
 	u16 nodeid, eventid;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EINVAL;
 
@@ -2471,7 +2468,8 @@ static int arm_cmn_probe(struct platform_device *pdev)
 	cmn->pmu = (struct pmu) {
 		.module = THIS_MODULE,
 		.attr_groups = arm_cmn_attr_groups,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr = perf_invalid_context,
 		.pmu_enable = arm_cmn_pmu_enable,
 		.pmu_disable = arm_cmn_pmu_disable,
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index 50b89b989ce7..d408cbb84ed7 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -676,9 +676,6 @@ static int arm_cspmu_event_init(struct perf_event *event)
 
 	cspmu = to_arm_cspmu(event->pmu);
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/*
 	 * Following other "uncore" PMUs, we do not support sampling mode or
 	 * attach to a task (per-process mode).
@@ -1186,7 +1183,8 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 	if (ret)
 		return ret;
 
-	capabilities = PERF_PMU_CAP_NO_EXCLUDE;
+	capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+		       PERF_PMU_CAP_NO_COMMON_EVENTS;
 	if (cspmu->irq == 0)
 		capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 
diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index 30cea6859574..dc0b5269edc1 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -515,9 +515,6 @@ static int dmc620_pmu_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/*
 	 * DMC 620 PMUs are shared across all cpus and cannot
 	 * support task bound and sampling events.
@@ -673,7 +670,8 @@ static int dmc620_pmu_device_probe(struct platform_device *pdev)
 
 	dmc620_pmu->pmu = (struct pmu) {
 		.module = THIS_MODULE,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr	= perf_invalid_context,
 		.event_init	= dmc620_pmu_event_init,
 		.add		= dmc620_pmu_add,
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 7ec4498e312f..f5ea5acaf2f3 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -544,9 +544,6 @@ static int dsu_pmu_event_init(struct perf_event *event)
 {
 	struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/* We don't support sampling */
 	if (is_sampling_event(event)) {
 		dev_dbg(dsu_pmu->pmu.dev, "Can't support sampling events\n");
@@ -762,7 +759,8 @@ static int dsu_pmu_device_probe(struct platform_device *pdev)
 		.read		= dsu_pmu_read,
 
 		.attr_groups	= dsu_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	rc = perf_pmu_register(&dsu_pmu->pmu, name, -1);
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index 6303b82566f9..ccecde79adb4 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -401,9 +401,6 @@ static int smmu_pmu_event_init(struct perf_event *event)
 	int group_num_events = 1;
 	u16 event_id;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (hwc->sample_period) {
 		dev_dbg(dev, "Sampling not supported\n");
 		return -EOPNOTSUPP;
@@ -870,7 +867,8 @@ static int smmu_pmu_probe(struct platform_device *pdev)
 		.stop		= smmu_pmu_event_stop,
 		.read		= smmu_pmu_event_read,
 		.attr_groups	= smmu_pmu_attr_grps,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	smmu_pmu->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res_0);
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index b622d75d8c9e..290e98247bba 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -699,10 +699,6 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	struct perf_event_attr *attr = &event->attr;
 	struct arm_spe_pmu *spe_pmu = to_spe_pmu(event->pmu);
 
-	/* This is, of course, deeply driver-specific */
-	if (attr->type != event->pmu->type)
-		return -ENOENT;
-
 	if (event->cpu >= 0 &&
 	    !cpumask_test_cpu(event->cpu, &spe_pmu->supported_cpus))
 		return -ENOENT;
@@ -932,7 +928,8 @@ static int arm_spe_pmu_perf_init(struct arm_spe_pmu *spe_pmu)
 
 	spe_pmu->pmu = (struct pmu) {
 		.module = THIS_MODULE,
-		.capabilities	= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE,
+		.capabilities	= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.attr_groups	= arm_spe_pmu_attr_groups,
 		/*
 		 * We hitch a ride on the software context here, so that
diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..57954d102a75 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -571,10 +571,6 @@ static int cxl_pmu_event_init(struct perf_event *event)
 	struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
 	int rc;
 
-	/* Top level type sanity check - is this a Hardware Event being requested */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 	/* TODO: Validation of any filter */
@@ -870,7 +866,8 @@ static int cxl_pmu_probe(struct device *dev)
 		.read = cxl_pmu_read,
 		.task_ctx_nr = perf_invalid_context,
 		.attr_groups = cxl_pmu_attr_groups,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	if (info->irq <= 0)
diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 957058ad0099..161faa98f627 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -366,9 +366,6 @@ static int dwc_pcie_pmu_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	u32 lane;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/* We don't support sampling */
 	if (is_sampling_event(event))
 		return -EINVAL;
@@ -636,7 +633,8 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
 		.parent		= &pdev->dev,
 		.module		= THIS_MODULE,
 		.attr_groups	= dwc_pcie_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr	= perf_invalid_context,
 		.event_init	= dwc_pcie_pmu_event_init,
 		.add		= dwc_pcie_pmu_event_add,
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 7dbfaee372c7..021d637aea06 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -398,9 +398,6 @@ static int ddr_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
@@ -651,7 +648,8 @@ static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 	*pmu = (struct ddr_pmu) {
 		.pmu = (struct pmu) {
 			.module	      = THIS_MODULE,
-			.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+			.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+					PERF_PMU_CAP_NO_COMMON_EVENTS,
 			.task_ctx_nr = perf_invalid_context,
 			.attr_groups = attr_groups,
 			.event_init  = ddr_perf_event_init,
diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
index 9685645bfe04..ec03e1e69568 100644
--- a/drivers/perf/fsl_imx9_ddr_perf.c
+++ b/drivers/perf/fsl_imx9_ddr_perf.c
@@ -416,9 +416,6 @@ static int ddr_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
@@ -528,7 +525,8 @@ static void ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 	*pmu = (struct ddr_pmu) {
 		.pmu = (struct pmu) {
 			.module       = THIS_MODULE,
-			.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+			.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+					PERF_PMU_CAP_NO_COMMON_EVENTS,
 			.task_ctx_nr  = perf_invalid_context,
 			.attr_groups  = attr_groups,
 			.event_init   = ddr_perf_event_init,
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index b90ba8aca3fa..5a301a7db7ae 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -353,10 +353,6 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event)
 	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	/* Check the type first before going on, otherwise it's not our event */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
 		hwc->event_base = HISI_PCIE_EXT_CNT;
 	else
@@ -813,7 +809,8 @@ static int hisi_pcie_alloc_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_
 		.read		= hisi_pcie_pmu_read,
 		.task_ctx_nr	= perf_invalid_context,
 		.attr_groups	= hisi_pcie_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	return 0;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 04031450d5fe..0908ddd992b7 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -186,9 +186,6 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct hisi_pmu *hisi_pmu;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/*
 	 * We do not support sampling as the counters are all
 	 * shared by all CPU cores in a CPU die(SCCL). Also we
@@ -548,7 +545,8 @@ void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 	pmu->stop               = hisi_uncore_pmu_stop;
 	pmu->read               = hisi_uncore_pmu_read;
 	pmu->attr_groups        = hisi_pmu->pmu_events.attr_groups;
-	pmu->capabilities       = PERF_PMU_CAP_NO_EXCLUDE;
+	pmu->capabilities       = PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS;
 }
 EXPORT_SYMBOL_GPL(hisi_pmu_init);
 
diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
index 16869bf5bf4c..300345edd211 100644
--- a/drivers/perf/hisilicon/hns3_pmu.c
+++ b/drivers/perf/hisilicon/hns3_pmu.c
@@ -1236,9 +1236,6 @@ static int hns3_pmu_event_init(struct perf_event *event)
 	int idx;
 	int ret;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/* Sampling is not supported */
 	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
@@ -1429,7 +1426,8 @@ static int hns3_pmu_alloc_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
 		.read		= hns3_pmu_read,
 		.task_ctx_nr	= perf_invalid_context,
 		.attr_groups	= hns3_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	return 0;
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 524ba82bfce2..baa0a3fbad31 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -325,9 +325,6 @@ static int cn10k_ddr_perf_event_init(struct perf_event *event)
 	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (is_sampling_event(event)) {
 		dev_info(pmu->dev, "Sampling not supported!\n");
 		return -EOPNOTSUPP;
@@ -656,7 +653,8 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 
 	ddr_pmu->pmu = (struct pmu) {
 		.module	      = THIS_MODULE,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr = perf_invalid_context,
 		.attr_groups = cn10k_attr_groups,
 		.event_init  = cn10k_ddr_perf_event_init,
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
index fec8e82edb95..bc2d642e87e8 100644
--- a/drivers/perf/marvell_cn10k_tad_pmu.c
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -140,9 +140,6 @@ static int tad_pmu_event_init(struct perf_event *event)
 {
 	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	if (!event->attr.disabled)
 		return -EINVAL;
 
@@ -321,7 +318,8 @@ static int tad_pmu_probe(struct platform_device *pdev)
 		.module		= THIS_MODULE,
 		.attr_groups	= tad_pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_INTERRUPT,
+				  PERF_PMU_CAP_NO_INTERRUPT |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr	= perf_invalid_context,
 
 		.event_init	= tad_pmu_event_init,
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 3f9a98c17a89..8b2617ad4bdc 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -440,12 +440,7 @@ static int l2_cache_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct cluster_pmu *cluster;
 	struct perf_event *sibling;
-	struct l2cache_pmu *l2cache_pmu;
-
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	l2cache_pmu = to_l2cache_pmu(event->pmu);
+	struct l2cache_pmu *l2cache_pmu = to_l2cache_pmu(event->pmu);
 
 	if (hwc->sample_period) {
 		dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
@@ -914,7 +909,8 @@ static int l2_cache_pmu_probe(struct platform_device *pdev)
 		.stop		= l2_cache_event_stop,
 		.read		= l2_cache_event_read,
 		.attr_groups	= l2_cache_pmu_attr_grps,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	l2cache_pmu->num_counters = get_num_counters();
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index f16783d03db7..72610777567d 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -480,12 +480,6 @@ static int qcom_l3_cache__event_init(struct perf_event *event)
 	struct l3cache_pmu *l3pmu = to_l3cache_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	/*
-	 * Is the event for this PMU?
-	 */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/*
 	 * Sampling not supported since these events are not core-attributable.
 	 */
@@ -760,7 +754,8 @@ static int qcom_l3_cache_pmu_probe(struct platform_device *pdev)
 		.read		= qcom_l3_cache__event_read,
 
 		.attr_groups	= qcom_l3_cache_pmu_attr_grps,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	l3pmu->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &memrc);
diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index 1edb9c03704f..8c7a2c6113be 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -574,10 +574,6 @@ static int tx2_uncore_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct tx2_uncore_pmu *tx2_pmu;
 
-	/* Test the event attr type check for PMU enumeration */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/*
 	 * SOC PMU counters are shared across all cores.
 	 * Therefore, it does not support per-process mode.
@@ -737,7 +733,8 @@ static int tx2_uncore_pmu_register(
 		.start		= tx2_uncore_event_start,
 		.stop		= tx2_uncore_event_stop,
 		.read		= tx2_uncore_event_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	tx2_pmu->pmu.name = devm_kasprintf(dev, GFP_KERNEL,
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 7ce344248dda..16bb3dfb1636 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -888,10 +888,6 @@ static int xgene_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hw = &event->hw;
 	struct perf_event *sibling;
 
-	/* Test the event attr type check for PMU enumeration */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	/*
 	 * SOC PMU counters are shared across all cores.
 	 * Therefore, it does not support per-process mode.
@@ -1112,7 +1108,8 @@ static int xgene_init_perf(struct xgene_pmu_dev *pmu_dev, char *name)
 		.start		= xgene_perf_start,
 		.stop		= xgene_perf_stop,
 		.read		= xgene_perf_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	/* Hardware counter init */
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (2 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 03/10] drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-13 12:05   ` kernel test robot
  2024-03-13 15:44   ` kernel test robot
  2024-03-12 17:34 ` [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently Robin Murphy
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

The PERF_PMU_CAP_NO_INTERRUPT flag is used by the core solely to
determine whether PMUs can support sampling events or not. It makes
sense to utilise the same capability for non-CPU-affine PMUs which have
no relevant state to sample, but it would be a rather confusing misnomer
when such PMUs do still have interrupts for handling overflows. Let's
rename it to represent what it actually means.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/arc/kernel/perf_event.c              | 2 +-
 arch/csky/kernel/perf_event.c             | 2 +-
 arch/powerpc/perf/8xx-pmu.c               | 2 +-
 arch/powerpc/perf/hv-24x7.c               | 2 +-
 arch/powerpc/perf/hv-gpci.c               | 2 +-
 arch/powerpc/platforms/pseries/papr_scm.c | 2 +-
 arch/s390/kernel/perf_cpum_cf.c           | 2 +-
 arch/sh/kernel/perf_event.c               | 2 +-
 arch/x86/events/amd/uncore.c              | 6 +++---
 arch/x86/events/core.c                    | 2 +-
 arch/x86/events/intel/cstate.c            | 6 +++---
 arch/x86/events/msr.c                     | 2 +-
 drivers/fpga/dfl-fme-perf.c               | 2 +-
 drivers/perf/arm_cspmu/arm_cspmu.c        | 2 +-
 drivers/perf/arm_pmu_platform.c           | 2 +-
 drivers/perf/marvell_cn10k_tad_pmu.c      | 2 +-
 drivers/perf/riscv_pmu_sbi.c              | 2 +-
 include/linux/perf_event.h                | 2 +-
 kernel/events/core.c                      | 2 +-
 19 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c
index adff957962da..cd02cf7904e8 100644
--- a/arch/arc/kernel/perf_event.c
+++ b/arch/arc/kernel/perf_event.c
@@ -819,7 +819,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
 	}
 
 	if (irq == -1)
-		arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+		arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING;
 
 	/*
 	 * perf parser doesn't really like '-' symbol in events name, so let's
diff --git a/arch/csky/kernel/perf_event.c b/arch/csky/kernel/perf_event.c
index e5f18420ce64..c733fb29114f 100644
--- a/arch/csky/kernel/perf_event.c
+++ b/arch/csky/kernel/perf_event.c
@@ -1315,7 +1315,7 @@ int csky_pmu_device_probe(struct platform_device *pdev,
 
 	ret = csky_pmu_request_irq(csky_pmu_handle_irq);
 	if (ret) {
-		csky_pmu.pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+		csky_pmu.pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING;
 		pr_notice("[perf] PMU request irq fail!\n");
 	}
 
diff --git a/arch/powerpc/perf/8xx-pmu.c b/arch/powerpc/perf/8xx-pmu.c
index 308a2e40d7be..456de23c2ea7 100644
--- a/arch/powerpc/perf/8xx-pmu.c
+++ b/arch/powerpc/perf/8xx-pmu.c
@@ -181,7 +181,7 @@ static struct pmu mpc8xx_pmu = {
 	.add		= mpc8xx_pmu_add,
 	.del		= mpc8xx_pmu_del,
 	.read		= mpc8xx_pmu_read,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT |
+	.capabilities	= PERF_PMU_CAP_NO_SAMPLING|
 			  PERF_PMU_CAP_NO_NMI,
 };
 
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 057ec2e3451d..74821bb193c1 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -1737,7 +1737,7 @@ static int hv_24x7_init(void)
 		return -ENOMEM;
 
 	/* sampling not supported */
-	h_24x7_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+	h_24x7_pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING
 
 	r = create_events_from_catalog(&event_group.attrs,
 				   &event_desc_group.attrs,
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
index 27f18119fda1..25842f61662c 100644
--- a/arch/powerpc/perf/hv-gpci.c
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -984,7 +984,7 @@ static int hv_gpci_init(void)
 		return r;
 
 	/* sampling not supported */
-	h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+	h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING
 
 	arg = (void *)get_cpu_var(hv_gpci_reqb);
 	memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 1a53e048ceb7..6415cdabe403 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -501,7 +501,7 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p)
 	nd_pmu->pmu.add = papr_scm_pmu_add;
 	nd_pmu->pmu.del = papr_scm_pmu_del;
 
-	nd_pmu->pmu.capabilities = PERF_PMU_CAP_NO_INTERRUPT |
+	nd_pmu->pmu.capabilities = PERF_PMU_CAP_NO_SAMPLING |
 				PERF_PMU_CAP_NO_EXCLUDE;
 
 	/*updating the cpumask variable */
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index 41ed6e0f0a2a..8474aafa2075 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -1054,7 +1054,7 @@ static void cpumf_pmu_del(struct perf_event *event, int flags)
 /* Performance monitoring unit for s390x */
 static struct pmu cpumf_pmu = {
 	.task_ctx_nr  = perf_sw_context,
-	.capabilities = PERF_PMU_CAP_NO_INTERRUPT,
+	.capabilities = PERF_PMU_CAP_NO_SAMPLING
 	.pmu_enable   = cpumf_pmu_enable,
 	.pmu_disable  = cpumf_pmu_disable,
 	.event_init   = cpumf_pmu_event_init,
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
index 1d2507f22437..4bade9b7d357 100644
--- a/arch/sh/kernel/perf_event.c
+++ b/arch/sh/kernel/perf_event.c
@@ -352,7 +352,7 @@ int register_sh_pmu(struct sh_pmu *_pmu)
 	 * no interrupts, and are therefore unable to do sampling without
 	 * further work and timer assistance.
 	 */
-	pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+	pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING
 
 	WARN_ON(_pmu->num_events > MAX_HWEVENTS);
 
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index 5bf03c575812..4220bf556962 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -700,7 +700,7 @@ int amd_uncore_df_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
 		.start		= amd_uncore_start,
 		.stop		= amd_uncore_stop,
 		.read		= amd_uncore_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_SAMPLING,
 		.module		= THIS_MODULE,
 	};
 
@@ -833,7 +833,7 @@ int amd_uncore_l3_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
 		.start		= amd_uncore_start,
 		.stop		= amd_uncore_stop,
 		.read		= amd_uncore_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_SAMPLING,
 		.module		= THIS_MODULE,
 	};
 
@@ -958,7 +958,7 @@ int amd_uncore_umc_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
 				.start		= amd_uncore_umc_start,
 				.stop		= amd_uncore_stop,
 				.read		= amd_uncore_read,
-				.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+				.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_SAMPLING,
 				.module		= THIS_MODULE,
 			};
 
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 09050641ce5d..20cded91716f 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1812,7 +1812,7 @@ static void __init pmu_check_apic(void)
 	 * events (user-space has to fall back and
 	 * sample via a hrtimer based software event):
 	 */
-	pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+	pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING
 
 }
 
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 4b50a3a9818a..3e4ab89d440c 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -530,7 +530,7 @@ static struct pmu cstate_core_pmu = {
 	.start		= cstate_pmu_event_start,
 	.stop		= cstate_pmu_event_stop,
 	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE,
 	.module		= THIS_MODULE,
 };
 
@@ -545,7 +545,7 @@ static struct pmu cstate_pkg_pmu = {
 	.start		= cstate_pmu_event_start,
 	.stop		= cstate_pmu_event_stop,
 	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE,
 	.module		= THIS_MODULE,
 };
 
@@ -560,7 +560,7 @@ static struct pmu cstate_module_pmu = {
 	.start		= cstate_pmu_event_start,
 	.stop		= cstate_pmu_event_stop,
 	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_CAP_NO_SAMPLING | PERF_PMU_CAP_NO_EXCLUDE,
 	.module		= THIS_MODULE,
 };
 
diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index 9e237b30f017..b33c0931d61d 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -296,7 +296,7 @@ static struct pmu pmu_msr = {
 	.start		= msr_event_start,
 	.stop		= msr_event_stop,
 	.read		= msr_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_CAP_NO_SAMPLING | PERF_PMU_CAP_NO_EXCLUDE,
 	.attr_update	= attr_update,
 };
 
diff --git a/drivers/fpga/dfl-fme-perf.c b/drivers/fpga/dfl-fme-perf.c
index 7422d2bc6f37..b5bafea06a55 100644
--- a/drivers/fpga/dfl-fme-perf.c
+++ b/drivers/fpga/dfl-fme-perf.c
@@ -921,7 +921,7 @@ static int fme_perf_pmu_register(struct platform_device *pdev,
 	pmu->start =		fme_perf_event_start;
 	pmu->stop =		fme_perf_event_stop;
 	pmu->read =		fme_perf_event_read;
-	pmu->capabilities =	PERF_PMU_CAP_NO_INTERRUPT |
+	pmu->capabilities =	PERF_PMU_CAP_NO_SAMPLING |
 				PERF_PMU_CAP_NO_EXCLUDE;
 
 	name = devm_kasprintf(priv->dev, GFP_KERNEL, "dfl_fme%d", pdev->id);
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index d408cbb84ed7..32ffea50cd7a 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -1186,7 +1186,7 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 	capabilities = PERF_PMU_CAP_NO_EXCLUDE |
 		       PERF_PMU_CAP_NO_COMMON_EVENTS;
 	if (cspmu->irq == 0)
-		capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+		capabilities |= PERF_PMU_CAP_NO_SAMPLING;
 
 	cspmu->pmu = (struct pmu){
 		.task_ctx_nr	= perf_invalid_context,
diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
index 3596db36cbff..e96c003f8555 100644
--- a/drivers/perf/arm_pmu_platform.c
+++ b/drivers/perf/arm_pmu_platform.c
@@ -109,7 +109,7 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
 	 */
 	if (num_irqs == 0) {
 		dev_warn(dev, "no irqs for PMU, sampling events not supported\n");
-		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING;
 		cpumask_setall(&pmu->supported_cpus);
 		return 0;
 	}
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
index bc2d642e87e8..aaedb5715d69 100644
--- a/drivers/perf/marvell_cn10k_tad_pmu.c
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -318,7 +318,7 @@ static int tad_pmu_probe(struct platform_device *pdev)
 		.module		= THIS_MODULE,
 		.attr_groups	= tad_pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_INTERRUPT |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr	= perf_invalid_context,
 
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 16acd4dcdb96..aa562520ecfd 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1049,7 +1049,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 	ret = pmu_sbi_setup_irqs(pmu, pdev);
 	if (ret < 0) {
 		pr_info("Perf sampling/filtering is not supported as sscof extension is not available\n");
-		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING;
 		pmu->pmu.capabilities |= PERF_PMU_CAP_NO_EXCLUDE;
 	}
 
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 983201f21dd2..b1fd832ed8bf 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -282,7 +282,7 @@ struct perf_event_pmu_context;
 /**
  * pmu::capabilities flags
  */
-#define PERF_PMU_CAP_NO_INTERRUPT		0x0001
+#define PERF_PMU_CAP_NO_SAMPLING		0x0001
 #define PERF_PMU_CAP_NO_NMI			0x0002
 #define PERF_PMU_CAP_AUX_NO_SG			0x0004
 #define PERF_PMU_CAP_EXTENDED_REGS		0x0008
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 7ad80826c218..892212aae85e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -12539,7 +12539,7 @@ SYSCALL_DEFINE5(perf_event_open,
 	}
 
 	if (is_sampling_event(event)) {
-		if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) {
+		if (event->pmu->capabilities & PERF_PMU_CAP_NO_SAMPLING) {
 			err = -EOPNOTSUPP;
 			goto err_alloc;
 		}
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (3 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-13 11:11   ` James Clark
  2024-03-12 17:34 ` [PATCH 06/10] drivers/perf: Clean up redundant per-task checks Robin Murphy
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

Our system PMUs fundamentally cannot support the current notion of
sampling events, so now that the core capability has been clarified,
apply it consistently and purge yet more boilerplate.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/alibaba_uncore_drw_pmu.c     |  6 +-----
 drivers/perf/amlogic/meson_ddr_pmu_core.c |  3 ++-
 drivers/perf/arm-cci.c                    |  3 ++-
 drivers/perf/arm-ccn.c                    | 12 +-----------
 drivers/perf/arm-cmn.c                    |  3 ++-
 drivers/perf/arm_cspmu/arm_cspmu.c        | 17 ++++-------------
 drivers/perf/arm_dmc620_pmu.c             |  4 ++--
 drivers/perf/arm_dsu_pmu.c                | 12 +-----------
 drivers/perf/arm_smmuv3_pmu.c             |  6 +-----
 drivers/perf/cxl_pmu.c                    |  3 ++-
 drivers/perf/dwc_pcie_pmu.c               |  5 +----
 drivers/perf/fsl_imx8_ddr_perf.c          |  3 ++-
 drivers/perf/fsl_imx9_ddr_perf.c          |  3 ++-
 drivers/perf/hisilicon/hisi_pcie_pmu.c    |  4 ++--
 drivers/perf/hisilicon/hisi_uncore_pmu.c  |  3 ++-
 drivers/perf/hisilicon/hns3_pmu.c         |  4 ++--
 drivers/perf/marvell_cn10k_ddr_pmu.c      |  6 +-----
 drivers/perf/qcom_l2_pmu.c                |  7 +------
 drivers/perf/qcom_l3_pmu.c                |  7 +------
 drivers/perf/thunderx2_pmu.c              |  4 ++--
 drivers/perf/xgene_pmu.c                  |  4 ++--
 21 files changed, 36 insertions(+), 83 deletions(-)

diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
index 606c2301bd11..eadf4118d1ec 100644
--- a/drivers/perf/alibaba_uncore_drw_pmu.c
+++ b/drivers/perf/alibaba_uncore_drw_pmu.c
@@ -535,11 +535,6 @@ static int ali_drw_pmu_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	struct device *dev = drw_pmu->pmu.dev;
 
-	if (is_sampling_event(event)) {
-		dev_err(dev, "Sampling not supported!\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (event->attach_state & PERF_ATTACH_TASK) {
 		dev_err(dev, "Per-task counter cannot allocate!\n");
 		return -EOPNOTSUPP;
@@ -707,6 +702,7 @@ static int ali_drw_pmu_probe(struct platform_device *pdev)
 		.read		= ali_drw_pmu_read,
 		.attr_groups	= ali_drw_pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
index c19b682297f3..3bc887cde163 100644
--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
+++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
@@ -121,7 +121,7 @@ static int meson_ddr_perf_event_init(struct perf_event *event)
 	u64 config1 = event->attr.config1;
 	u64 config2 = event->attr.config2;
 
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	if (event->cpu < 0)
@@ -490,6 +490,7 @@ int meson_ddr_pmu_create(struct platform_device *pdev)
 		.pmu = {
 			.module		= THIS_MODULE,
 			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+					  PERF_PMU_CAP_NO_SAMPLING |
 					  PERF_PMU_CAP_NO_COMMON_EVENTS,
 			.task_ctx_nr	= perf_invalid_context,
 			.attr_groups	= attr_groups,
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index f157bfd4b923..cf8fa2474bed 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1313,7 +1313,7 @@ static int cci_pmu_event_init(struct perf_event *event)
 	int err = 0;
 
 	/* Shared by all CPUs, no meaningful state to sample */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	/*
@@ -1414,6 +1414,7 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
 		.read		= pmu_read,
 		.attr_groups	= pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index ce26bb773a56..4114349e62dd 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -713,7 +713,6 @@ static void arm_ccn_pmu_event_release(struct perf_event *event)
 static int arm_ccn_pmu_event_init(struct perf_event *event)
 {
 	struct arm_ccn *ccn;
-	struct hw_perf_event *hw = &event->hw;
 	u32 node_xp, type, event_id;
 	int valid;
 	int i;
@@ -721,16 +720,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
 
 	ccn = pmu_to_arm_ccn(event->pmu);
 
-	if (hw->sample_period) {
-		dev_dbg(ccn->dev, "Sampling not supported!\n");
-		return -EOPNOTSUPP;
-	}
-
-	if (has_branch_stack(event)) {
-		dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
-		return -EINVAL;
-	}
-
 	if (event->cpu < 0) {
 		dev_dbg(ccn->dev, "Can't provide per-task data!\n");
 		return -EOPNOTSUPP;
@@ -1273,6 +1262,7 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
 		.pmu_enable = arm_ccn_pmu_enable,
 		.pmu_disable = arm_ccn_pmu_disable,
 		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_SAMPLING |
 				PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 717dd90417d6..e1f151f04c9f 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -1696,7 +1696,7 @@ static int arm_cmn_event_init(struct perf_event *event)
 	bool bynodeid;
 	u16 nodeid, eventid;
 
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EINVAL;
 
 	event->cpu = cmn->cpu;
@@ -2469,6 +2469,7 @@ static int arm_cmn_probe(struct platform_device *pdev)
 		.module = THIS_MODULE,
 		.attr_groups = arm_cmn_attr_groups,
 		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_SAMPLING |
 				PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr = perf_invalid_context,
 		.pmu_enable = arm_cmn_pmu_enable,
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index 32ffea50cd7a..c5c7198e6921 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -680,12 +680,6 @@ static int arm_cspmu_event_init(struct perf_event *event)
 	 * Following other "uncore" PMUs, we do not support sampling mode or
 	 * attach to a task (per-process mode).
 	 */
-	if (is_sampling_event(event)) {
-		dev_dbg(cspmu->pmu.dev,
-			"Can't support sampling events\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK) {
 		dev_dbg(cspmu->pmu.dev,
 			"Can't support per-task counters\n");
@@ -1171,7 +1165,7 @@ static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu)
 
 static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 {
-	int ret, capabilities;
+	int ret;
 	struct attribute_group **attr_groups;
 
 	attr_groups = arm_cspmu_alloc_attr_group(cspmu);
@@ -1183,11 +1177,6 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 	if (ret)
 		return ret;
 
-	capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-		       PERF_PMU_CAP_NO_COMMON_EVENTS;
-	if (cspmu->irq == 0)
-		capabilities |= PERF_PMU_CAP_NO_SAMPLING;
-
 	cspmu->pmu = (struct pmu){
 		.task_ctx_nr	= perf_invalid_context,
 		.module		= cspmu->impl.module,
@@ -1200,7 +1189,9 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 		.stop		= arm_cspmu_stop,
 		.read		= arm_cspmu_read,
 		.attr_groups	= (const struct attribute_group **)attr_groups,
-		.capabilities	= capabilities,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
+				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
 	/* Hardware counter init */
diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index dc0b5269edc1..47d3a166bccc 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -519,8 +519,7 @@ static int dmc620_pmu_event_init(struct perf_event *event)
 	 * DMC 620 PMUs are shared across all cpus and cannot
 	 * support task bound and sampling events.
 	 */
-	if (is_sampling_event(event) ||
-		event->attach_state & PERF_ATTACH_TASK) {
+	if (event->attach_state & PERF_ATTACH_TASK) {
 		dev_dbg(dmc620_pmu->pmu.dev,
 			"Can't support per-task counters\n");
 		return -EOPNOTSUPP;
@@ -671,6 +670,7 @@ static int dmc620_pmu_device_probe(struct platform_device *pdev)
 	dmc620_pmu->pmu = (struct pmu) {
 		.module = THIS_MODULE,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr	= perf_invalid_context,
 		.event_init	= dmc620_pmu_event_init,
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index f5ea5acaf2f3..3424d165795c 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -544,23 +544,12 @@ static int dsu_pmu_event_init(struct perf_event *event)
 {
 	struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
 
-	/* We don't support sampling */
-	if (is_sampling_event(event)) {
-		dev_dbg(dsu_pmu->pmu.dev, "Can't support sampling events\n");
-		return -EOPNOTSUPP;
-	}
-
 	/* We cannot support task bound events */
 	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK) {
 		dev_dbg(dsu_pmu->pmu.dev, "Can't support per-task counters\n");
 		return -EINVAL;
 	}
 
-	if (has_branch_stack(event)) {
-		dev_dbg(dsu_pmu->pmu.dev, "Can't support filtering\n");
-		return -EINVAL;
-	}
-
 	if (!cpumask_test_cpu(event->cpu, &dsu_pmu->associated_cpus)) {
 		dev_dbg(dsu_pmu->pmu.dev,
 			 "Requested cpu is not associated with the DSU\n");
@@ -760,6 +749,7 @@ static int dsu_pmu_device_probe(struct platform_device *pdev)
 
 		.attr_groups	= dsu_pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index ccecde79adb4..8206ba0c1637 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -401,11 +401,6 @@ static int smmu_pmu_event_init(struct perf_event *event)
 	int group_num_events = 1;
 	u16 event_id;
 
-	if (hwc->sample_period) {
-		dev_dbg(dev, "Sampling not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (event->cpu < 0) {
 		dev_dbg(dev, "Per-task mode not supported\n");
 		return -EOPNOTSUPP;
@@ -868,6 +863,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
 		.read		= smmu_pmu_event_read,
 		.attr_groups	= smmu_pmu_attr_grps,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 57954d102a75..41afbbd221a9 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -571,7 +571,7 @@ static int cxl_pmu_event_init(struct perf_event *event)
 	struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
 	int rc;
 
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 	/* TODO: Validation of any filter */
 
@@ -867,6 +867,7 @@ static int cxl_pmu_probe(struct device *dev)
 		.task_ctx_nr = perf_invalid_context,
 		.attr_groups = cxl_pmu_attr_groups,
 		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_SAMPLING |
 				PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 161faa98f627..638ad527f252 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -366,10 +366,6 @@ static int dwc_pcie_pmu_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	u32 lane;
 
-	/* We don't support sampling */
-	if (is_sampling_event(event))
-		return -EINVAL;
-
 	/* We cannot support task bound events */
 	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK)
 		return -EINVAL;
@@ -634,6 +630,7 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
 		.module		= THIS_MODULE,
 		.attr_groups	= dwc_pcie_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr	= perf_invalid_context,
 		.event_init	= dwc_pcie_pmu_event_init,
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 021d637aea06..0070f2bd4d88 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -398,7 +398,7 @@ static int ddr_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	if (event->cpu < 0) {
@@ -649,6 +649,7 @@ static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 		.pmu = (struct pmu) {
 			.module	      = THIS_MODULE,
 			.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+					PERF_PMU_CAP_NO_SAMPLING |
 					PERF_PMU_CAP_NO_COMMON_EVENTS,
 			.task_ctx_nr = perf_invalid_context,
 			.attr_groups = attr_groups,
diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
index ec03e1e69568..83822abf8031 100644
--- a/drivers/perf/fsl_imx9_ddr_perf.c
+++ b/drivers/perf/fsl_imx9_ddr_perf.c
@@ -416,7 +416,7 @@ static int ddr_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	if (event->cpu < 0) {
@@ -526,6 +526,7 @@ static void ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 		.pmu = (struct pmu) {
 			.module       = THIS_MODULE,
 			.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+					PERF_PMU_CAP_NO_SAMPLING |
 					PERF_PMU_CAP_NO_COMMON_EVENTS,
 			.task_ctx_nr  = perf_invalid_context,
 			.attr_groups  = attr_groups,
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 5a301a7db7ae..7579b93dc462 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -358,8 +358,7 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event)
 	else
 		hwc->event_base = HISI_PCIE_CNT;
 
-	/* Sampling is not supported. */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu))
@@ -810,6 +809,7 @@ static int hisi_pcie_alloc_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_
 		.task_ctx_nr	= perf_invalid_context,
 		.attr_groups	= hisi_pcie_pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 0908ddd992b7..7718b031f671 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -191,7 +191,7 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
 	 * shared by all CPU cores in a CPU die(SCCL). Also we
 	 * do not support attach to a task(per-process mode)
 	 */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	/*
@@ -546,6 +546,7 @@ void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 	pmu->read               = hisi_uncore_pmu_read;
 	pmu->attr_groups        = hisi_pmu->pmu_events.attr_groups;
 	pmu->capabilities       = PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS;
 }
 EXPORT_SYMBOL_GPL(hisi_pmu_init);
diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
index 300345edd211..3d089df22c01 100644
--- a/drivers/perf/hisilicon/hns3_pmu.c
+++ b/drivers/perf/hisilicon/hns3_pmu.c
@@ -1236,8 +1236,7 @@ static int hns3_pmu_event_init(struct perf_event *event)
 	int idx;
 	int ret;
 
-	/* Sampling is not supported */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
 	event->cpu = hns3_pmu->on_cpu;
@@ -1427,6 +1426,7 @@ static int hns3_pmu_alloc_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
 		.task_ctx_nr	= perf_invalid_context,
 		.attr_groups	= hns3_pmu_attr_groups,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index baa0a3fbad31..bb16a193ff36 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -325,11 +325,6 @@ static int cn10k_ddr_perf_event_init(struct perf_event *event)
 	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	if (is_sampling_event(event)) {
-		dev_info(pmu->dev, "Sampling not supported!\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (event->cpu < 0) {
 		dev_warn(pmu->dev, "Can't provide per-task data!\n");
 		return -EOPNOTSUPP;
@@ -654,6 +649,7 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 	ddr_pmu->pmu = (struct pmu) {
 		.module	      = THIS_MODULE,
 		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
+				PERF_PMU_CAP_NO_SAMPLING |
 				PERF_PMU_CAP_NO_COMMON_EVENTS,
 		.task_ctx_nr = perf_invalid_context,
 		.attr_groups = cn10k_attr_groups,
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 8b2617ad4bdc..3f7837632988 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -442,12 +442,6 @@ static int l2_cache_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	struct l2cache_pmu *l2cache_pmu = to_l2cache_pmu(event->pmu);
 
-	if (hwc->sample_period) {
-		dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
-				    "Sampling not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (event->cpu < 0) {
 		dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
 				    "Per-task mode not supported\n");
@@ -910,6 +904,7 @@ static int l2_cache_pmu_probe(struct platform_device *pdev)
 		.read		= l2_cache_event_read,
 		.attr_groups	= l2_cache_pmu_attr_grps,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index 72610777567d..54fde33802f4 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -480,12 +480,6 @@ static int qcom_l3_cache__event_init(struct perf_event *event)
 	struct l3cache_pmu *l3pmu = to_l3cache_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	/*
-	 * Sampling not supported since these events are not core-attributable.
-	 */
-	if (hwc->sample_period)
-		return -EINVAL;
-
 	/*
 	 * Task mode not available, we run the counters as socket counters,
 	 * not attributable to any CPU and therefore cannot attribute per-task.
@@ -755,6 +749,7 @@ static int qcom_l3_cache_pmu_probe(struct platform_device *pdev)
 
 		.attr_groups	= qcom_l3_cache_pmu_attr_grps,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index 8c7a2c6113be..06b589799536 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -577,9 +577,8 @@ static int tx2_uncore_event_init(struct perf_event *event)
 	/*
 	 * SOC PMU counters are shared across all cores.
 	 * Therefore, it does not support per-process mode.
-	 * Also, it does not support event sampling mode.
 	 */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EINVAL;
 
 	if (event->cpu < 0)
@@ -734,6 +733,7 @@ static int tx2_uncore_pmu_register(
 		.stop		= tx2_uncore_event_stop,
 		.read		= tx2_uncore_event_read,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 16bb3dfb1636..7f753b8f4e93 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -891,9 +891,8 @@ static int xgene_perf_event_init(struct perf_event *event)
 	/*
 	 * SOC PMU counters are shared across all cores.
 	 * Therefore, it does not support per-process mode.
-	 * Also, it does not support event sampling mode.
 	 */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EINVAL;
 
 	if (event->cpu < 0)
@@ -1109,6 +1108,7 @@ static int xgene_init_perf(struct xgene_pmu_dev *pmu_dev, char *name)
 		.stop		= xgene_perf_stop,
 		.read		= xgene_perf_read,
 		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_SAMPLING |
 				  PERF_PMU_CAP_NO_COMMON_EVENTS,
 	};
 
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 06/10] drivers/perf: Clean up redundant per-task checks
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (4 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-12 17:34 ` [PATCH 07/10] perf: Define common uncore capabilities Robin Murphy
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

It turns out that a while back, perf_event_alloc() grew the ability
to properly refuse all per-task and cgroup events on behalf of
uncore/system PMUs using perf_invalid_context, so that's a whole load
more inconsistent boilerplate which can also go from our drivers. This
includes a couple more cases of drivers foolishly checking event->cpu
*after* overriding it with their own (necessarily valid) CPU...

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/alibaba_uncore_drw_pmu.c     |  5 -----
 drivers/perf/amlogic/meson_ddr_pmu_core.c |  6 ------
 drivers/perf/arm-cci.c                    |  6 ------
 drivers/perf/arm-ccn.c                    |  4 ----
 drivers/perf/arm-cmn.c                    |  5 -----
 drivers/perf/arm_cspmu/arm_cspmu.c        | 10 ----------
 drivers/perf/arm_dmc620_pmu.c             | 12 ------------
 drivers/perf/arm_dsu_pmu.c                |  6 ------
 drivers/perf/arm_smmuv3_pmu.c             |  5 -----
 drivers/perf/cxl_pmu.c                    |  2 --
 drivers/perf/dwc_pcie_pmu.c               |  4 ----
 drivers/perf/fsl_imx8_ddr_perf.c          |  8 --------
 drivers/perf/fsl_imx9_ddr_perf.c          |  8 --------
 drivers/perf/hisilicon/hisi_pcie_pmu.c    |  3 ---
 drivers/perf/hisilicon/hisi_uncore_pmu.c  | 15 ---------------
 drivers/perf/hisilicon/hns3_pmu.c         |  3 ---
 drivers/perf/marvell_cn10k_ddr_pmu.c      |  5 -----
 drivers/perf/qcom_l2_pmu.c                |  6 ------
 drivers/perf/qcom_l3_pmu.c                |  7 -------
 drivers/perf/thunderx2_pmu.c              | 10 ----------
 drivers/perf/xgene_pmu.c                  |  9 ---------
 21 files changed, 139 deletions(-)

diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
index eadf4118d1ec..42172939721b 100644
--- a/drivers/perf/alibaba_uncore_drw_pmu.c
+++ b/drivers/perf/alibaba_uncore_drw_pmu.c
@@ -535,11 +535,6 @@ static int ali_drw_pmu_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	struct device *dev = drw_pmu->pmu.dev;
 
-	if (event->attach_state & PERF_ATTACH_TASK) {
-		dev_err(dev, "Per-task counter cannot allocate!\n");
-		return -EOPNOTSUPP;
-	}
-
 	event->cpu = drw_pmu->irq->cpu;
 
 	if (event->group_leader != event &&
diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
index 3bc887cde163..6fcd37b11dd8 100644
--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
+++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
@@ -121,12 +121,6 @@ static int meson_ddr_perf_event_init(struct perf_event *event)
 	u64 config1 = event->attr.config1;
 	u64 config2 = event->attr.config2;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
-	if (event->cpu < 0)
-		return -EOPNOTSUPP;
-
 	/* check if the number of parameters is too much */
 	if (event->attr.config != ALL_CHAN_COUNTER_ID &&
 	    hweight64(config1) + hweight64(config2) > MAX_AXI_PORTS_OF_CHANNEL)
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index cf8fa2474bed..2ccce0e66ada 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1312,10 +1312,6 @@ static int cci_pmu_event_init(struct perf_event *event)
 	atomic_t *active_events = &cci_pmu->active_events;
 	int err = 0;
 
-	/* Shared by all CPUs, no meaningful state to sample */
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
 	/*
 	 * Following the example set by other "uncore" PMUs, we accept any CPU
 	 * and rewrite its affinity dynamically rather than having perf core
@@ -1325,8 +1321,6 @@ static int cci_pmu_event_init(struct perf_event *event)
 	 * the event being installed into its context, so the PMU's CPU can't
 	 * change under our feet.
 	 */
-	if (event->cpu < 0)
-		return -EINVAL;
 	event->cpu = cci_pmu->cpu;
 
 	event->destroy = hw_perf_event_destroy;
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 4114349e62dd..2adb6a1d136f 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -720,10 +720,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
 
 	ccn = pmu_to_arm_ccn(event->pmu);
 
-	if (event->cpu < 0) {
-		dev_dbg(ccn->dev, "Can't provide per-task data!\n");
-		return -EOPNOTSUPP;
-	}
 	/*
 	 * Many perf core operations (eg. events rotation) operate on a
 	 * single CPU context. This is obvious for CPU PMUs, where one
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index e1f151f04c9f..26ede1db1f72 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -1696,12 +1696,7 @@ static int arm_cmn_event_init(struct perf_event *event)
 	bool bynodeid;
 	u16 nodeid, eventid;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
 	event->cpu = cmn->cpu;
-	if (event->cpu < 0)
-		return -EINVAL;
 
 	type = CMN_EVENT_TYPE(event);
 	/* DTC events (i.e. cycles) already have everything they need */
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index c5c7198e6921..b007e1fdd336 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -676,16 +676,6 @@ static int arm_cspmu_event_init(struct perf_event *event)
 
 	cspmu = to_arm_cspmu(event->pmu);
 
-	/*
-	 * Following other "uncore" PMUs, we do not support sampling mode or
-	 * attach to a task (per-process mode).
-	 */
-	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK) {
-		dev_dbg(cspmu->pmu.dev,
-			"Can't support per-task counters\n");
-		return -EINVAL;
-	}
-
 	/*
 	 * Make sure the CPU assignment is on one of the CPUs associated with
 	 * this PMU.
diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index 47d3a166bccc..98e7c2333cc6 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -515,16 +515,6 @@ static int dmc620_pmu_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	/*
-	 * DMC 620 PMUs are shared across all cpus and cannot
-	 * support task bound and sampling events.
-	 */
-	if (event->attach_state & PERF_ATTACH_TASK) {
-		dev_dbg(dmc620_pmu->pmu.dev,
-			"Can't support per-task counters\n");
-		return -EOPNOTSUPP;
-	}
-
 	/*
 	 * Many perf core operations (eg. events rotation) operate on a
 	 * single CPU context. This is obvious for CPU PMUs, where one
@@ -535,8 +525,6 @@ static int dmc620_pmu_event_init(struct perf_event *event)
 	 * processor.
 	 */
 	event->cpu = dmc620_pmu->irq->cpu;
-	if (event->cpu < 0)
-		return -EINVAL;
 
 	/*
 	 * We can't atomically disable all HW counters so only one event allowed,
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 3424d165795c..740f8c958976 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -544,12 +544,6 @@ static int dsu_pmu_event_init(struct perf_event *event)
 {
 	struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
 
-	/* We cannot support task bound events */
-	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK) {
-		dev_dbg(dsu_pmu->pmu.dev, "Can't support per-task counters\n");
-		return -EINVAL;
-	}
-
 	if (!cpumask_test_cpu(event->cpu, &dsu_pmu->associated_cpus)) {
 		dev_dbg(dsu_pmu->pmu.dev,
 			 "Requested cpu is not associated with the DSU\n");
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index 8206ba0c1637..f4e22ff179b9 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -401,11 +401,6 @@ static int smmu_pmu_event_init(struct perf_event *event)
 	int group_num_events = 1;
 	u16 event_id;
 
-	if (event->cpu < 0) {
-		dev_dbg(dev, "Per-task mode not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	/* Verify specified event is supported on this PMU */
 	event_id = get_event(event);
 	if (event_id < SMMU_PMCG_ARCH_MAX_EVENTS &&
diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 41afbbd221a9..e78f8db8ef52 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -571,8 +571,6 @@ static int cxl_pmu_event_init(struct perf_event *event)
 	struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
 	int rc;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
 	/* TODO: Validation of any filter */
 
 	/*
diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 638ad527f252..c2c4a7673e58 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -366,10 +366,6 @@ static int dwc_pcie_pmu_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	u32 lane;
 
-	/* We cannot support task bound events */
-	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
 	if (event->group_leader != event &&
 	    !is_software_event(event->group_leader))
 		return -EINVAL;
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 0070f2bd4d88..612216277ea5 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -398,14 +398,6 @@ static int ddr_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
-	if (event->cpu < 0) {
-		dev_warn(pmu->dev, "Can't provide per-task data!\n");
-		return -EOPNOTSUPP;
-	}
-
 	/*
 	 * We must NOT create groups containing mixed PMUs, although software
 	 * events are acceptable (for example to create a CCN group
diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
index 83822abf8031..80b4703bef89 100644
--- a/drivers/perf/fsl_imx9_ddr_perf.c
+++ b/drivers/perf/fsl_imx9_ddr_perf.c
@@ -416,14 +416,6 @@ static int ddr_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct perf_event *sibling;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
-	if (event->cpu < 0) {
-		dev_warn(pmu->dev, "Can't provide per-task data!\n");
-		return -EOPNOTSUPP;
-	}
-
 	/*
 	 * We must NOT create groups containing mixed PMUs, although software
 	 * events are acceptable (for example to create a CCN group
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 7579b93dc462..d37c65d40a30 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -358,9 +358,6 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event)
 	else
 		hwc->event_base = HISI_PCIE_CNT;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
 	if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu))
 		return -EINVAL;
 
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 7718b031f671..5de53e76e42f 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -186,21 +186,6 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct hisi_pmu *hisi_pmu;
 
-	/*
-	 * We do not support sampling as the counters are all
-	 * shared by all CPU cores in a CPU die(SCCL). Also we
-	 * do not support attach to a task(per-process mode)
-	 */
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
-	/*
-	 *  The uncore counters not specific to any CPU, so cannot
-	 *  support per-task
-	 */
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	/*
 	 * Validate if the events in group does not exceed the
 	 * available counters in hardware.
diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
index 3d089df22c01..09bf38e56909 100644
--- a/drivers/perf/hisilicon/hns3_pmu.c
+++ b/drivers/perf/hisilicon/hns3_pmu.c
@@ -1236,9 +1236,6 @@ static int hns3_pmu_event_init(struct perf_event *event)
 	int idx;
 	int ret;
 
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
 	event->cpu = hns3_pmu->on_cpu;
 
 	idx = hns3_pmu_get_event_idx(hns3_pmu);
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index bb16a193ff36..ebafa39a6b24 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -325,11 +325,6 @@ static int cn10k_ddr_perf_event_init(struct perf_event *event)
 	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	if (event->cpu < 0) {
-		dev_warn(pmu->dev, "Can't provide per-task data!\n");
-		return -EOPNOTSUPP;
-	}
-
 	/*  We must NOT create groups containing mixed PMUs */
 	if (event->group_leader->pmu != event->pmu &&
 	    !is_software_event(event->group_leader))
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index 3f7837632988..d85f11c9261f 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -442,12 +442,6 @@ static int l2_cache_event_init(struct perf_event *event)
 	struct perf_event *sibling;
 	struct l2cache_pmu *l2cache_pmu = to_l2cache_pmu(event->pmu);
 
-	if (event->cpu < 0) {
-		dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
-				    "Per-task mode not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	if (((L2_EVT_GROUP(event->attr.config) > L2_EVT_GROUP_MAX) ||
 	     ((event->attr.config & ~L2_EVT_MASK) != 0)) &&
 	    (event->attr.config != L2CYCLE_CTR_RAW_CODE)) {
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index 54fde33802f4..733067fa68e5 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -480,13 +480,6 @@ static int qcom_l3_cache__event_init(struct perf_event *event)
 	struct l3cache_pmu *l3pmu = to_l3cache_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 
-	/*
-	 * Task mode not available, we run the counters as socket counters,
-	 * not attributable to any CPU and therefore cannot attribute per-task.
-	 */
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	/* Validate the group */
 	if (!qcom_l3_cache__validate_event_group(event))
 		return -EINVAL;
diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index 06b589799536..d9da3070f27c 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -574,16 +574,6 @@ static int tx2_uncore_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	struct tx2_uncore_pmu *tx2_pmu;
 
-	/*
-	 * SOC PMU counters are shared across all cores.
-	 * Therefore, it does not support per-process mode.
-	 */
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	tx2_pmu = pmu_to_tx2_pmu(event->pmu);
 	if (tx2_pmu->cpu >= nr_cpu_ids)
 		return -EINVAL;
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 7f753b8f4e93..b2d855866354 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -888,15 +888,6 @@ static int xgene_perf_event_init(struct perf_event *event)
 	struct hw_perf_event *hw = &event->hw;
 	struct perf_event *sibling;
 
-	/*
-	 * SOC PMU counters are shared across all cores.
-	 * Therefore, it does not support per-process mode.
-	 */
-	if (event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
-	if (event->cpu < 0)
-		return -EINVAL;
 	/*
 	 * Many perf core operations (eg. events rotation) operate on a
 	 * single CPU context. This is obvious for CPU PMUs, where one
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 07/10] perf: Define common uncore capabilities
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (5 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 06/10] drivers/perf: Clean up redundant per-task checks Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-13 11:23   ` James Clark
  2024-03-12 17:34 ` [PATCH 08/10] drivers/perf: Use " Robin Murphy
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

Nearly all uncore/system PMUs share a common set of capbilities,
so let's wrap those up in a single macro for ease of use.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 include/linux/perf_event.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index b1fd832ed8bf..5d5db122005b 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -293,6 +293,9 @@ struct perf_event_pmu_context;
 #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
 #define PERF_PMU_CAP_NO_COMMON_EVENTS		0x0200
 
+#define PERF_PMU_UNCORE_CAPS \
+(PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_COMMON_EVENTS)
+
 struct perf_output_handle;
 
 #define PMU_NULL_DEV	((void *)(~0UL))
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 08/10] drivers/perf: Use common uncore capabilities
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (6 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 07/10] perf: Define common uncore capabilities Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-12 17:34 ` [PATCH 09/10] x86: Use common uncore PMU capabilities Robin Murphy
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang

Now that we've ratified it, adopt PERF_PMU_UNCORE_CAPS.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/perf/alibaba_uncore_drw_pmu.c     | 4 +---
 drivers/perf/amlogic/meson_ddr_pmu_core.c | 4 +---
 drivers/perf/arm-cci.c                    | 4 +---
 drivers/perf/arm-ccn.c                    | 4 +---
 drivers/perf/arm-cmn.c                    | 4 +---
 drivers/perf/arm_cspmu/arm_cspmu.c        | 4 +---
 drivers/perf/arm_dmc620_pmu.c             | 4 +---
 drivers/perf/arm_dsu_pmu.c                | 4 +---
 drivers/perf/arm_smmuv3_pmu.c             | 4 +---
 drivers/perf/cxl_pmu.c                    | 4 +---
 drivers/perf/dwc_pcie_pmu.c               | 4 +---
 drivers/perf/fsl_imx8_ddr_perf.c          | 4 +---
 drivers/perf/fsl_imx9_ddr_perf.c          | 4 +---
 drivers/perf/hisilicon/hisi_pcie_pmu.c    | 4 +---
 drivers/perf/hisilicon/hisi_uncore_pmu.c  | 4 +---
 drivers/perf/hisilicon/hns3_pmu.c         | 4 +---
 drivers/perf/marvell_cn10k_ddr_pmu.c      | 4 +---
 drivers/perf/marvell_cn10k_tad_pmu.c      | 4 +---
 drivers/perf/qcom_l2_pmu.c                | 4 +---
 drivers/perf/qcom_l3_pmu.c                | 4 +---
 drivers/perf/thunderx2_pmu.c              | 4 +---
 drivers/perf/xgene_pmu.c                  | 4 +---
 22 files changed, 22 insertions(+), 66 deletions(-)

diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c
index 42172939721b..9bacb79a86c4 100644
--- a/drivers/perf/alibaba_uncore_drw_pmu.c
+++ b/drivers/perf/alibaba_uncore_drw_pmu.c
@@ -696,9 +696,7 @@ static int ali_drw_pmu_probe(struct platform_device *pdev)
 		.stop		= ali_drw_pmu_stop,
 		.read		= ali_drw_pmu_read,
 		.attr_groups	= ali_drw_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	ret = perf_pmu_register(&drw_pmu->pmu, name, -1);
diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
index 6fcd37b11dd8..e6370ea08231 100644
--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
+++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
@@ -483,9 +483,7 @@ int meson_ddr_pmu_create(struct platform_device *pdev)
 	*pmu = (struct ddr_pmu) {
 		.pmu = {
 			.module		= THIS_MODULE,
-			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-					  PERF_PMU_CAP_NO_SAMPLING |
-					  PERF_PMU_CAP_NO_COMMON_EVENTS,
+			.capabilities	= PERF_PMU_UNCORE_CAPS,
 			.task_ctx_nr	= perf_invalid_context,
 			.attr_groups	= attr_groups,
 			.event_init	= meson_ddr_perf_event_init,
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 2ccce0e66ada..916e9881adf9 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1407,9 +1407,7 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
 		.stop		= cci_pmu_stop,
 		.read		= pmu_read,
 		.attr_groups	= pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	cci_pmu->plat_device = pdev;
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
index 2adb6a1d136f..3f2f41ee476e 100644
--- a/drivers/perf/arm-ccn.c
+++ b/drivers/perf/arm-ccn.c
@@ -1257,9 +1257,7 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
 		.read = arm_ccn_pmu_event_read,
 		.pmu_enable = arm_ccn_pmu_enable,
 		.pmu_disable = arm_ccn_pmu_disable,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-				PERF_PMU_CAP_NO_SAMPLING |
-				PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities = PERF_PMU_UNCORE_CAPS,
 	};
 
 	/* No overflow interrupt? Have to use a timer instead. */
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 26ede1db1f72..e779da94351a 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -2463,9 +2463,7 @@ static int arm_cmn_probe(struct platform_device *pdev)
 	cmn->pmu = (struct pmu) {
 		.module = THIS_MODULE,
 		.attr_groups = arm_cmn_attr_groups,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-				PERF_PMU_CAP_NO_SAMPLING |
-				PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities = PERF_PMU_UNCORE_CAPS,
 		.task_ctx_nr = perf_invalid_context,
 		.pmu_enable = arm_cmn_pmu_enable,
 		.pmu_disable = arm_cmn_pmu_disable,
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index b007e1fdd336..2d9cb2ac0213 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -1179,9 +1179,7 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 		.stop		= arm_cspmu_stop,
 		.read		= arm_cspmu_read,
 		.attr_groups	= (const struct attribute_group **)attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	/* Hardware counter init */
diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
index 98e7c2333cc6..047bff8733c4 100644
--- a/drivers/perf/arm_dmc620_pmu.c
+++ b/drivers/perf/arm_dmc620_pmu.c
@@ -657,9 +657,7 @@ static int dmc620_pmu_device_probe(struct platform_device *pdev)
 
 	dmc620_pmu->pmu = (struct pmu) {
 		.module = THIS_MODULE,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 		.task_ctx_nr	= perf_invalid_context,
 		.event_init	= dmc620_pmu_event_init,
 		.add		= dmc620_pmu_add,
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 740f8c958976..8d97ef86f9a8 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -742,9 +742,7 @@ static int dsu_pmu_device_probe(struct platform_device *pdev)
 		.read		= dsu_pmu_read,
 
 		.attr_groups	= dsu_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	rc = perf_pmu_register(&dsu_pmu->pmu, name, -1);
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index f4e22ff179b9..34669d1314a4 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -857,9 +857,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
 		.stop		= smmu_pmu_event_stop,
 		.read		= smmu_pmu_event_read,
 		.attr_groups	= smmu_pmu_attr_grps,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	smmu_pmu->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res_0);
diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index e78f8db8ef52..8b7548192245 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -864,9 +864,7 @@ static int cxl_pmu_probe(struct device *dev)
 		.read = cxl_pmu_read,
 		.task_ctx_nr = perf_invalid_context,
 		.attr_groups = cxl_pmu_attr_groups,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-				PERF_PMU_CAP_NO_SAMPLING |
-				PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities = PERF_PMU_UNCORE_CAPS,
 	};
 
 	if (info->irq <= 0)
diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index c2c4a7673e58..bb8d77b470ce 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -625,9 +625,7 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
 		.parent		= &pdev->dev,
 		.module		= THIS_MODULE,
 		.attr_groups	= dwc_pcie_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 		.task_ctx_nr	= perf_invalid_context,
 		.event_init	= dwc_pcie_pmu_event_init,
 		.add		= dwc_pcie_pmu_event_add,
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 612216277ea5..1f250ff3075b 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -640,9 +640,7 @@ static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 	*pmu = (struct ddr_pmu) {
 		.pmu = (struct pmu) {
 			.module	      = THIS_MODULE,
-			.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-					PERF_PMU_CAP_NO_SAMPLING |
-					PERF_PMU_CAP_NO_COMMON_EVENTS,
+			.capabilities = PERF_PMU_UNCORE_CAPS,
 			.task_ctx_nr = perf_invalid_context,
 			.attr_groups = attr_groups,
 			.event_init  = ddr_perf_event_init,
diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
index 80b4703bef89..a9156f17886b 100644
--- a/drivers/perf/fsl_imx9_ddr_perf.c
+++ b/drivers/perf/fsl_imx9_ddr_perf.c
@@ -517,9 +517,7 @@ static void ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 	*pmu = (struct ddr_pmu) {
 		.pmu = (struct pmu) {
 			.module       = THIS_MODULE,
-			.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-					PERF_PMU_CAP_NO_SAMPLING |
-					PERF_PMU_CAP_NO_COMMON_EVENTS,
+			.capabilities = PERF_PMU_UNCORE_CAPS,
 			.task_ctx_nr  = perf_invalid_context,
 			.attr_groups  = attr_groups,
 			.event_init   = ddr_perf_event_init,
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index d37c65d40a30..35f0407f4e10 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -805,9 +805,7 @@ static int hisi_pcie_alloc_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_
 		.read		= hisi_pcie_pmu_read,
 		.task_ctx_nr	= perf_invalid_context,
 		.attr_groups	= hisi_pcie_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	return 0;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 5de53e76e42f..25d1e704ea25 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -530,9 +530,7 @@ void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 	pmu->stop               = hisi_uncore_pmu_stop;
 	pmu->read               = hisi_uncore_pmu_read;
 	pmu->attr_groups        = hisi_pmu->pmu_events.attr_groups;
-	pmu->capabilities       = PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS;
+	pmu->capabilities       = PERF_PMU_UNCORE_CAPS;
 }
 EXPORT_SYMBOL_GPL(hisi_pmu_init);
 
diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
index 09bf38e56909..34b1ca3f0bb6 100644
--- a/drivers/perf/hisilicon/hns3_pmu.c
+++ b/drivers/perf/hisilicon/hns3_pmu.c
@@ -1422,9 +1422,7 @@ static int hns3_pmu_alloc_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
 		.read		= hns3_pmu_read,
 		.task_ctx_nr	= perf_invalid_context,
 		.attr_groups	= hns3_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	return 0;
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index ebafa39a6b24..ee69077a9320 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -643,9 +643,7 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 
 	ddr_pmu->pmu = (struct pmu) {
 		.module	      = THIS_MODULE,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE |
-				PERF_PMU_CAP_NO_SAMPLING |
-				PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities = PERF_PMU_UNCORE_CAPS,
 		.task_ctx_nr = perf_invalid_context,
 		.attr_groups = cn10k_attr_groups,
 		.event_init  = cn10k_ddr_perf_event_init,
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
index aaedb5715d69..c83924a094dc 100644
--- a/drivers/perf/marvell_cn10k_tad_pmu.c
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -317,9 +317,7 @@ static int tad_pmu_probe(struct platform_device *pdev)
 
 		.module		= THIS_MODULE,
 		.attr_groups	= tad_pmu_attr_groups,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 		.task_ctx_nr	= perf_invalid_context,
 
 		.event_init	= tad_pmu_event_init,
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index d85f11c9261f..67e69e0293aa 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -897,9 +897,7 @@ static int l2_cache_pmu_probe(struct platform_device *pdev)
 		.stop		= l2_cache_event_stop,
 		.read		= l2_cache_event_read,
 		.attr_groups	= l2_cache_pmu_attr_grps,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	l2cache_pmu->num_counters = get_num_counters();
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
index 733067fa68e5..f545c01aa671 100644
--- a/drivers/perf/qcom_l3_pmu.c
+++ b/drivers/perf/qcom_l3_pmu.c
@@ -741,9 +741,7 @@ static int qcom_l3_cache_pmu_probe(struct platform_device *pdev)
 		.read		= qcom_l3_cache__event_read,
 
 		.attr_groups	= qcom_l3_cache_pmu_attr_grps,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	l3pmu->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &memrc);
diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index d9da3070f27c..c1e2372f57c5 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -722,9 +722,7 @@ static int tx2_uncore_pmu_register(
 		.start		= tx2_uncore_event_start,
 		.stop		= tx2_uncore_event_stop,
 		.read		= tx2_uncore_event_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	tx2_pmu->pmu.name = devm_kasprintf(dev, GFP_KERNEL,
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index b2d855866354..8cc6989857e8 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -1098,9 +1098,7 @@ static int xgene_init_perf(struct xgene_pmu_dev *pmu_dev, char *name)
 		.start		= xgene_perf_start,
 		.stop		= xgene_perf_stop,
 		.read		= xgene_perf_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
-				  PERF_PMU_CAP_NO_SAMPLING |
-				  PERF_PMU_CAP_NO_COMMON_EVENTS,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 	};
 
 	/* Hardware counter init */
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 09/10] x86: Use common uncore PMU capabilities
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (7 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 08/10] drivers/perf: Use " Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-12 17:34 ` [PATCH 10/10] ARM: " Robin Murphy
  2024-03-13 11:26 ` [PATCH 00/10] perf: Clean up common uncore boilerplate James Clark
  10 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Thomas Gleixner, Borislav Petkov, Dave Hansen

Switch the x86 uncore PMU drivers over to the new common capabilities,
allowing to remove all the checks that perf core now takes care of.

CC: Thomas Gleixner <tglx@linutronix.de>
CC: Borislav Petkov <bp@alien8.de>
CC: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/x86/events/amd/iommu.c        | 17 +----------------
 arch/x86/events/amd/power.c        | 10 +---------
 arch/x86/events/amd/uncore.c       | 12 +++---------
 arch/x86/events/intel/cstate.c     | 16 +++-------------
 arch/x86/events/intel/uncore.c     | 11 +----------
 arch/x86/events/intel/uncore_snb.c | 20 +++-----------------
 arch/x86/events/msr.c              |  9 +--------
 arch/x86/events/rapl.c             |  9 +--------
 8 files changed, 14 insertions(+), 90 deletions(-)

diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c
index b15f7b950d2e..dd4cabb40865 100644
--- a/arch/x86/events/amd/iommu.c
+++ b/arch/x86/events/amd/iommu.c
@@ -207,21 +207,6 @@ static int perf_iommu_event_init(struct perf_event *event)
 {
 	struct hw_perf_event *hwc = &event->hw;
 
-	/* test the event attr type check for PMU enumeration */
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/*
-	 * IOMMU counters are shared across all cores.
-	 * Therefore, it does not support per-process mode.
-	 * Also, it does not support event sampling mode.
-	 */
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	/* update the hw_perf_event struct with the iommu config data */
 	hwc->conf  = event->attr.config;
 	hwc->conf1 = event->attr.config1;
@@ -412,7 +397,7 @@ static const struct pmu iommu_pmu __initconst = {
 	.read		= perf_iommu_read,
 	.task_ctx_nr	= perf_invalid_context,
 	.attr_groups	= amd_iommu_attr_groups,
-	.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 };
 
 static __init int init_one_iommu(unsigned int idx)
diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c
index 37d5b380516e..d528517df93e 100644
--- a/arch/x86/events/amd/power.c
+++ b/arch/x86/events/amd/power.c
@@ -124,14 +124,6 @@ static int pmu_event_init(struct perf_event *event)
 {
 	u64 cfg = event->attr.config & AMD_POWER_EVENT_MASK;
 
-	/* Only look at AMD power events. */
-	if (event->attr.type != pmu_class.type)
-		return -ENOENT;
-
-	/* Unsupported modes and filters. */
-	if (event->attr.sample_period)
-		return -EINVAL;
-
 	if (cfg != AMD_POWER_EVENTSEL_PKG)
 		return -EINVAL;
 
@@ -212,7 +204,7 @@ static struct pmu pmu_class = {
 	.start		= pmu_event_start,
 	.stop		= pmu_event_stop,
 	.read		= pmu_event_read,
-	.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 	.module		= THIS_MODULE,
 };
 
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index 4220bf556962..6e97ee4ccf4d 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -209,12 +209,6 @@ static int amd_uncore_event_init(struct perf_event *event)
 	struct amd_uncore_ctx *ctx;
 	struct hw_perf_event *hwc = &event->hw;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	pmu = event_to_amd_uncore_pmu(event);
 	ctx = *per_cpu_ptr(pmu->ctx, event->cpu);
 	if (!ctx)
@@ -700,7 +694,7 @@ int amd_uncore_df_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
 		.start		= amd_uncore_start,
 		.stop		= amd_uncore_stop,
 		.read		= amd_uncore_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_SAMPLING,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 		.module		= THIS_MODULE,
 	};
 
@@ -833,7 +827,7 @@ int amd_uncore_l3_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
 		.start		= amd_uncore_start,
 		.stop		= amd_uncore_stop,
 		.read		= amd_uncore_read,
-		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_SAMPLING,
+		.capabilities	= PERF_PMU_UNCORE_CAPS,
 		.module		= THIS_MODULE,
 	};
 
@@ -958,7 +952,7 @@ int amd_uncore_umc_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
 				.start		= amd_uncore_umc_start,
 				.stop		= amd_uncore_stop,
 				.read		= amd_uncore_read,
-				.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_SAMPLING,
+				.capabilities	= PERF_PMU_UNCORE_CAPS,
 				.module		= THIS_MODULE,
 			};
 
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 3e4ab89d440c..58d6e5b483c5 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -319,16 +319,6 @@ static int cstate_pmu_event_init(struct perf_event *event)
 	u64 cfg = event->attr.config;
 	int cpu;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/* unsupported modes and filters */
-	if (event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	if (event->pmu == &cstate_core_pmu) {
 		if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
 			return -EINVAL;
@@ -530,7 +520,7 @@ static struct pmu cstate_core_pmu = {
 	.start		= cstate_pmu_event_start,
 	.stop		= cstate_pmu_event_stop,
 	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 	.module		= THIS_MODULE,
 };
 
@@ -545,7 +535,7 @@ static struct pmu cstate_pkg_pmu = {
 	.start		= cstate_pmu_event_start,
 	.stop		= cstate_pmu_event_stop,
 	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 	.module		= THIS_MODULE,
 };
 
@@ -560,7 +550,7 @@ static struct pmu cstate_module_pmu = {
 	.start		= cstate_pmu_event_start,
 	.stop		= cstate_pmu_event_stop,
 	.read		= cstate_pmu_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_SAMPLING | PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 	.module		= THIS_MODULE,
 };
 
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 7927c0b832fa..031d5aff297a 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -736,24 +736,15 @@ static int uncore_pmu_event_init(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	int ret;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	pmu = uncore_event_to_pmu(event);
 	/* no device found for this pmu */
 	if (pmu->func_id < 0)
 		return -ENOENT;
 
-	/* Sampling not supported yet */
-	if (hwc->sample_period)
-		return -EINVAL;
-
 	/*
 	 * Place all uncore events for a particular physical package
 	 * onto a single cpu
 	 */
-	if (event->cpu < 0)
-		return -EINVAL;
 	box = uncore_pmu_to_box(pmu, event->cpu);
 	if (!box || box->cpu < 0)
 		return -EINVAL;
@@ -919,7 +910,7 @@ static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
 			.stop		= uncore_pmu_event_stop,
 			.read		= uncore_pmu_event_read,
 			.module		= THIS_MODULE,
-			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+			.capabilities	= PERF_PMU_UNCORE_CAPS,
 			.attr_update	= pmu->type->attr_update,
 		};
 	} else {
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index 7fd4334e12a1..2af53e3f16c1 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -876,33 +876,19 @@ static int snb_uncore_imc_event_init(struct perf_event *event)
 	u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK;
 	int idx, base;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
 	pmu = uncore_event_to_pmu(event);
 	/* no device found for this pmu */
 	if (pmu->func_id < 0)
 		return -ENOENT;
 
-	/* Sampling not supported yet */
-	if (hwc->sample_period)
-		return -EINVAL;
-
-	/* unsupported modes and filters */
-	if (event->attr.sample_period) /* no sampling */
+	/* check only supported bits are set */
+	if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
 		return -EINVAL;
 
 	/*
 	 * Place all uncore events for a particular physical package
 	 * onto a single cpu
 	 */
-	if (event->cpu < 0)
-		return -EINVAL;
-
-	/* check only supported bits are set */
-	if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK)
-		return -EINVAL;
-
 	box = uncore_pmu_to_box(pmu, event->cpu);
 	if (!box || box->cpu < 0)
 		return -EINVAL;
@@ -1013,7 +999,7 @@ static struct pmu snb_uncore_imc_pmu = {
 	.start		= uncore_pmu_event_start,
 	.stop		= uncore_pmu_event_stop,
 	.read		= uncore_pmu_event_read,
-	.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 };
 
 static struct intel_uncore_ops snb_uncore_imc_ops = {
diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index b33c0931d61d..af8dd83aca48 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -204,13 +204,6 @@ static int msr_event_init(struct perf_event *event)
 {
 	u64 cfg = event->attr.config;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	/* unsupported modes and filters */
-	if (event->attr.sample_period) /* no sampling */
-		return -EINVAL;
-
 	if (cfg >= PERF_MSR_EVENT_MAX)
 		return -EINVAL;
 
@@ -296,7 +289,7 @@ static struct pmu pmu_msr = {
 	.start		= msr_event_start,
 	.stop		= msr_event_stop,
 	.read		= msr_event_update,
-	.capabilities	= PERF_PMU_CAP_NO_SAMPLING | PERF_PMU_CAP_NO_EXCLUDE,
+	.capabilities	= PERF_PMU_UNCORE_CAPS,
 	.attr_update	= attr_update,
 };
 
diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c
index 8d98d468b976..34b054970c3d 100644
--- a/arch/x86/events/rapl.c
+++ b/arch/x86/events/rapl.c
@@ -328,17 +328,10 @@ static int rapl_pmu_event_init(struct perf_event *event)
 	int bit, ret = 0;
 	struct rapl_pmu *pmu;
 
-	/* only look at RAPL events */
-	if (event->attr.type != rapl_pmus->pmu.type)
-		return -ENOENT;
-
 	/* check only supported bits are set */
 	if (event->attr.config & ~RAPL_EVENT_MASK)
 		return -EINVAL;
 
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG;
 
 	if (!cfg || cfg >= NR_RAPL_DOMAINS + 1)
@@ -693,7 +686,7 @@ static int __init init_rapl_pmus(void)
 	rapl_pmus->pmu.stop		= rapl_pmu_event_stop;
 	rapl_pmus->pmu.read		= rapl_pmu_event_read;
 	rapl_pmus->pmu.module		= THIS_MODULE;
-	rapl_pmus->pmu.capabilities	= PERF_PMU_CAP_NO_EXCLUDE;
+	rapl_pmus->pmu.capabilities	= PERF_PMU_UNCORE_CAPS;
 	return 0;
 }
 
-- 
2.39.2.101.g768bb238c484.dirty


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

* [PATCH 10/10] ARM: Use common uncore PMU capabilities
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (8 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 09/10] x86: Use common uncore PMU capabilities Robin Murphy
@ 2024-03-12 17:34 ` Robin Murphy
  2024-03-30 14:59   ` Shawn Guo
  2024-03-13 11:26 ` [PATCH 00/10] perf: Clean up common uncore boilerplate James Clark
  10 siblings, 1 reply; 21+ messages in thread
From: Robin Murphy @ 2024-03-12 17:34 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Russell King, Shawn Guo, Sascha Hauer

Switch the ARM system PMU drivers over to the new common capabilities,
allowing to remove all the checks that perf core now takes care of.

CC: Russell King <linux@armlinux.org.uk>
CC: Shawn Guo <shawnguo@kernel.org>
CC: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm/mach-imx/mmdc.c     | 16 +---------------
 arch/arm/mm/cache-l2x0-pmu.c | 12 +-----------
 2 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 444a7eaa320c..806ab6675b37 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -280,20 +280,6 @@ static int mmdc_pmu_event_init(struct perf_event *event)
 	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
 	int cfg = event->attr.config;
 
-	if (event->attr.type != event->pmu->type)
-		return -ENOENT;
-
-	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
-		return -EOPNOTSUPP;
-
-	if (event->cpu < 0) {
-		dev_warn(pmu_mmdc->dev, "Can't provide per-task data!\n");
-		return -EOPNOTSUPP;
-	}
-
-	if (event->attr.sample_period)
-		return -EINVAL;
-
 	if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
 		return -EINVAL;
 
@@ -445,7 +431,7 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
 			.start          = mmdc_pmu_event_start,
 			.stop           = mmdc_pmu_event_stop,
 			.read           = mmdc_pmu_event_update,
-			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+			.capabilities	= PERF_PMU_UNCORE_CAPS,
 		},
 		.mmdc_base = mmdc_base,
 		.dev = dev,
diff --git a/arch/arm/mm/cache-l2x0-pmu.c b/arch/arm/mm/cache-l2x0-pmu.c
index 993fefdc167a..a2567d953fdb 100644
--- a/arch/arm/mm/cache-l2x0-pmu.c
+++ b/arch/arm/mm/cache-l2x0-pmu.c
@@ -295,16 +295,6 @@ static int l2x0_pmu_event_init(struct perf_event *event)
 {
 	struct hw_perf_event *hw = &event->hw;
 
-	if (event->attr.type != l2x0_pmu->type)
-		return -ENOENT;
-
-	if (is_sampling_event(event) ||
-	    event->attach_state & PERF_ATTACH_TASK)
-		return -EINVAL;
-
-	if (event->cpu < 0)
-		return -EINVAL;
-
 	if (event->attr.config & ~L2X0_EVENT_CNT_CFG_SRC_MASK)
 		return -EINVAL;
 
@@ -524,7 +514,7 @@ static __init int l2x0_pmu_init(void)
 		.del = l2x0_pmu_event_del,
 		.event_init = l2x0_pmu_event_init,
 		.attr_groups = l2x0_pmu_attr_groups,
-		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.capabilities = PERF_PMU_UNCORE_CAPS,
 	};
 
 	l2x0_pmu_reset();
-- 
2.39.2.101.g768bb238c484.dirty


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

* Re: [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently
  2024-03-12 17:34 ` [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently Robin Murphy
@ 2024-03-13 11:11   ` James Clark
  2024-03-13 12:02     ` Robin Murphy
  0 siblings, 1 reply; 21+ messages in thread
From: James Clark @ 2024-03-13 11:11 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon



On 12/03/2024 17:34, Robin Murphy wrote:
> Our system PMUs fundamentally cannot support the current notion of
> sampling events, so now that the core capability has been clarified,
> apply it consistently and purge yet more boilerplate.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  drivers/perf/alibaba_uncore_drw_pmu.c     |  6 +-----
>  drivers/perf/amlogic/meson_ddr_pmu_core.c |  3 ++-
>  drivers/perf/arm-cci.c                    |  3 ++-
>  drivers/perf/arm-ccn.c                    | 12 +-----------
>  drivers/perf/arm-cmn.c                    |  3 ++-
>  drivers/perf/arm_cspmu/arm_cspmu.c        | 17 ++++-------------
>  drivers/perf/arm_dmc620_pmu.c             |  4 ++--
>  drivers/perf/arm_dsu_pmu.c                | 12 +-----------
>  drivers/perf/arm_smmuv3_pmu.c             |  6 +-----
>  drivers/perf/cxl_pmu.c                    |  3 ++-
>  drivers/perf/dwc_pcie_pmu.c               |  5 +----
>  drivers/perf/fsl_imx8_ddr_perf.c          |  3 ++-
>  drivers/perf/fsl_imx9_ddr_perf.c          |  3 ++-
>  drivers/perf/hisilicon/hisi_pcie_pmu.c    |  4 ++--
>  drivers/perf/hisilicon/hisi_uncore_pmu.c  |  3 ++-
>  drivers/perf/hisilicon/hns3_pmu.c         |  4 ++--
>  drivers/perf/marvell_cn10k_ddr_pmu.c      |  6 +-----
>  drivers/perf/qcom_l2_pmu.c                |  7 +------
>  drivers/perf/qcom_l3_pmu.c                |  7 +------
>  drivers/perf/thunderx2_pmu.c              |  4 ++--
>  drivers/perf/xgene_pmu.c                  |  4 ++--
>  21 files changed, 36 insertions(+), 83 deletions(-)
> 
[...]
>  
> diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
> index ce26bb773a56..4114349e62dd 100644
> --- a/drivers/perf/arm-ccn.c
> +++ b/drivers/perf/arm-ccn.c
> @@ -713,7 +713,6 @@ static void arm_ccn_pmu_event_release(struct perf_event *event)
>  static int arm_ccn_pmu_event_init(struct perf_event *event)
>  {
>  	struct arm_ccn *ccn;
> -	struct hw_perf_event *hw = &event->hw;
>  	u32 node_xp, type, event_id;
>  	int valid;
>  	int i;
> @@ -721,16 +720,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
>  
>  	ccn = pmu_to_arm_ccn(event->pmu);
>  
> -	if (hw->sample_period) {
> -		dev_dbg(ccn->dev, "Sampling not supported!\n");
> -		return -EOPNOTSUPP;
> -	}
> -
> -	if (has_branch_stack(event)) {
> -		dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
> -		return -EINVAL;
> -	}
> -

[...]

> diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
> index f5ea5acaf2f3..3424d165795c 100644
> --- a/drivers/perf/arm_dsu_pmu.c
> +++ b/drivers/perf/arm_dsu_pmu.c
> @@ -544,23 +544,12 @@ static int dsu_pmu_event_init(struct perf_event *event)
>  {
>  	struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
>  
> -	/* We don't support sampling */
> -	if (is_sampling_event(event)) {
> -		dev_dbg(dsu_pmu->pmu.dev, "Can't support sampling events\n");
> -		return -EOPNOTSUPP;
> -	}
> -
>  	/* We cannot support task bound events */
>  	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK) {
>  		dev_dbg(dsu_pmu->pmu.dev, "Can't support per-task counters\n");
>  		return -EINVAL;
>  	}
>  
> -	if (has_branch_stack(event)) {
> -		dev_dbg(dsu_pmu->pmu.dev, "Can't support filtering\n");
> -		return -EINVAL;
> -	}
> -

I'm assuming that this and the other has_branch_stack() check were
removed because branch stacks don't actually do anything unless sampling
is enabled?

It's a small difference that there is now no error message if you ask
for branch stacks, but it wouldn't have done anything anyway? I suppose
this error message was also not applied very consistently across the
different devices.

James


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

* Re: [PATCH 07/10] perf: Define common uncore capabilities
  2024-03-12 17:34 ` [PATCH 07/10] perf: Define common uncore capabilities Robin Murphy
@ 2024-03-13 11:23   ` James Clark
  2024-03-13 12:24     ` Robin Murphy
  0 siblings, 1 reply; 21+ messages in thread
From: James Clark @ 2024-03-13 11:23 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon



On 12/03/2024 17:34, Robin Murphy wrote:
> Nearly all uncore/system PMUs share a common set of capbilities,
> so let's wrap those up in a single macro for ease of use.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  include/linux/perf_event.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index b1fd832ed8bf..5d5db122005b 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -293,6 +293,9 @@ struct perf_event_pmu_context;
>  #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
>  #define PERF_PMU_CAP_NO_COMMON_EVENTS		0x0200
>  
> +#define PERF_PMU_UNCORE_CAPS \
> +(PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_COMMON_EVENTS)
> +

The most minor of nits: missing space before |. There is another one in
another commit that triggers checkpatch but that line gets deleted anyway.

>  struct perf_output_handle;
>  
>  #define PMU_NULL_DEV	((void *)(~0UL))

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

* Re: [PATCH 00/10] perf: Clean up common uncore boilerplate
  2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
                   ` (9 preceding siblings ...)
  2024-03-12 17:34 ` [PATCH 10/10] ARM: " Robin Murphy
@ 2024-03-13 11:26 ` James Clark
  10 siblings, 0 replies; 21+ messages in thread
From: James Clark @ 2024-03-13 11:26 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon



On 12/03/2024 17:34, Robin Murphy wrote:
> Hi all,
> 
> Since this came up yet again recently, and it's an idea which has been
> nagging me for years, I decided it was time to see how hard it really
> would be to start shaving this yak. And it turns out to be refreshingly
> simple - the core code has quietly become capable of doing most of what
> we want, the one new functional addition is trivial (patch #2), and the
> resulting largely-mechanical cleanup seems a pretty nice win.
> 
> This series is focused on drivers/perf/ as that's where most mess is
> concentrated, but figured I'd include the arch/ patches as well since
> they might be reasonable to land with the core changes, at least for x86
> (FWIW I did also look at the powerpc drivers but they scared me and I
> ran away; sorry). The remaining stragglers elsewhere around the tree I'd
> come back to as a follow-up.
> 
> (And yes, I appreciate it's mid-merge-window already, but since I do
> have a tree-wide rename proposed here, may as well give the discussion
> a chance for a head start before -rc1...)
> 
> Thanks,
> Robin.
> 
> 
Reviewed-by: James Clark <james.clark@arm.com>

> Robin Murphy (10):
>   perf/alibaba_uncore_drw: Use correct CPU affinity
>   perf: Add capability for common event support
>   drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS
>   perf: Rename PERF_PMU_CAP_NO_INTERRUPT
>   drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently
>   drivers/perf: Clean up redundant per-task checks
>   perf: Define common uncore capabilities
>   drivers/perf: Use common uncore capabilities
>   x86: Use common uncore PMU capabilities
>   ARM: Use common uncore PMU capabilities
> 
>  arch/arc/kernel/perf_event.c              |  2 +-
>  arch/arm/mach-imx/mmdc.c                  | 16 +-------------
>  arch/arm/mm/cache-l2x0-pmu.c              | 12 +---------
>  arch/csky/kernel/perf_event.c             |  2 +-
>  arch/powerpc/perf/8xx-pmu.c               |  2 +-
>  arch/powerpc/perf/hv-24x7.c               |  2 +-
>  arch/powerpc/perf/hv-gpci.c               |  2 +-
>  arch/powerpc/platforms/pseries/papr_scm.c |  2 +-
>  arch/s390/kernel/perf_cpum_cf.c           |  2 +-
>  arch/sh/kernel/perf_event.c               |  2 +-
>  arch/x86/events/amd/iommu.c               | 17 +-------------
>  arch/x86/events/amd/power.c               | 10 +--------
>  arch/x86/events/amd/uncore.c              | 12 +++-------
>  arch/x86/events/core.c                    |  2 +-
>  arch/x86/events/intel/cstate.c            | 16 +++-----------
>  arch/x86/events/intel/uncore.c            | 11 +--------
>  arch/x86/events/intel/uncore_snb.c        | 20 +++--------------
>  arch/x86/events/msr.c                     |  9 +-------
>  arch/x86/events/rapl.c                    |  9 +-------
>  drivers/fpga/dfl-fme-perf.c               |  2 +-
>  drivers/perf/alibaba_uncore_drw_pmu.c     | 27 +++--------------------
>  drivers/perf/amlogic/meson_ddr_pmu_core.c | 11 +--------
>  drivers/perf/arm-cci.c                    | 15 +------------
>  drivers/perf/arm-ccn.c                    | 20 +----------------
>  drivers/perf/arm-cmn.c                    | 10 +--------
>  drivers/perf/arm_cspmu/arm_cspmu.c        | 27 ++---------------------
>  drivers/perf/arm_dmc620_pmu.c             | 18 +--------------
>  drivers/perf/arm_dsu_pmu.c                | 22 +-----------------
>  drivers/perf/arm_pmu_platform.c           |  2 +-
>  drivers/perf/arm_smmuv3_pmu.c             | 15 +------------
>  drivers/perf/arm_spe_pmu.c                |  7 ++----
>  drivers/perf/cxl_pmu.c                    |  8 +------
>  drivers/perf/dwc_pcie_pmu.c               | 13 +----------
>  drivers/perf/fsl_imx8_ddr_perf.c          | 13 +----------
>  drivers/perf/fsl_imx9_ddr_perf.c          | 13 +----------
>  drivers/perf/hisilicon/hisi_pcie_pmu.c    | 10 +--------
>  drivers/perf/hisilicon/hisi_uncore_pmu.c  | 20 +----------------
>  drivers/perf/hisilicon/hns3_pmu.c         |  9 +-------
>  drivers/perf/marvell_cn10k_ddr_pmu.c      | 15 +------------
>  drivers/perf/marvell_cn10k_tad_pmu.c      |  6 +----
>  drivers/perf/qcom_l2_pmu.c                | 21 ++----------------
>  drivers/perf/qcom_l3_pmu.c                | 21 +-----------------
>  drivers/perf/riscv_pmu_sbi.c              |  2 +-
>  drivers/perf/thunderx2_pmu.c              | 17 +-------------
>  drivers/perf/xgene_pmu.c                  | 16 +-------------
>  include/linux/perf_event.h                |  6 ++++-
>  kernel/events/core.c                      |  7 +++++-
>  47 files changed, 67 insertions(+), 456 deletions(-)
> 

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

* Re: [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently
  2024-03-13 11:11   ` James Clark
@ 2024-03-13 12:02     ` Robin Murphy
  0 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-13 12:02 UTC (permalink / raw)
  To: James Clark
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon

On 2024-03-13 11:11 am, James Clark wrote:
> 
> 
> On 12/03/2024 17:34, Robin Murphy wrote:
>> Our system PMUs fundamentally cannot support the current notion of
>> sampling events, so now that the core capability has been clarified,
>> apply it consistently and purge yet more boilerplate.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   drivers/perf/alibaba_uncore_drw_pmu.c     |  6 +-----
>>   drivers/perf/amlogic/meson_ddr_pmu_core.c |  3 ++-
>>   drivers/perf/arm-cci.c                    |  3 ++-
>>   drivers/perf/arm-ccn.c                    | 12 +-----------
>>   drivers/perf/arm-cmn.c                    |  3 ++-
>>   drivers/perf/arm_cspmu/arm_cspmu.c        | 17 ++++-------------
>>   drivers/perf/arm_dmc620_pmu.c             |  4 ++--
>>   drivers/perf/arm_dsu_pmu.c                | 12 +-----------
>>   drivers/perf/arm_smmuv3_pmu.c             |  6 +-----
>>   drivers/perf/cxl_pmu.c                    |  3 ++-
>>   drivers/perf/dwc_pcie_pmu.c               |  5 +----
>>   drivers/perf/fsl_imx8_ddr_perf.c          |  3 ++-
>>   drivers/perf/fsl_imx9_ddr_perf.c          |  3 ++-
>>   drivers/perf/hisilicon/hisi_pcie_pmu.c    |  4 ++--
>>   drivers/perf/hisilicon/hisi_uncore_pmu.c  |  3 ++-
>>   drivers/perf/hisilicon/hns3_pmu.c         |  4 ++--
>>   drivers/perf/marvell_cn10k_ddr_pmu.c      |  6 +-----
>>   drivers/perf/qcom_l2_pmu.c                |  7 +------
>>   drivers/perf/qcom_l3_pmu.c                |  7 +------
>>   drivers/perf/thunderx2_pmu.c              |  4 ++--
>>   drivers/perf/xgene_pmu.c                  |  4 ++--
>>   21 files changed, 36 insertions(+), 83 deletions(-)
>>
> [...]
>>   
>> diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
>> index ce26bb773a56..4114349e62dd 100644
>> --- a/drivers/perf/arm-ccn.c
>> +++ b/drivers/perf/arm-ccn.c
>> @@ -713,7 +713,6 @@ static void arm_ccn_pmu_event_release(struct perf_event *event)
>>   static int arm_ccn_pmu_event_init(struct perf_event *event)
>>   {
>>   	struct arm_ccn *ccn;
>> -	struct hw_perf_event *hw = &event->hw;
>>   	u32 node_xp, type, event_id;
>>   	int valid;
>>   	int i;
>> @@ -721,16 +720,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
>>   
>>   	ccn = pmu_to_arm_ccn(event->pmu);
>>   
>> -	if (hw->sample_period) {
>> -		dev_dbg(ccn->dev, "Sampling not supported!\n");
>> -		return -EOPNOTSUPP;
>> -	}
>> -
>> -	if (has_branch_stack(event)) {
>> -		dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
>> -		return -EINVAL;
>> -	}
>> -
> 
> [...]
> 
>> diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
>> index f5ea5acaf2f3..3424d165795c 100644
>> --- a/drivers/perf/arm_dsu_pmu.c
>> +++ b/drivers/perf/arm_dsu_pmu.c
>> @@ -544,23 +544,12 @@ static int dsu_pmu_event_init(struct perf_event *event)
>>   {
>>   	struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
>>   
>> -	/* We don't support sampling */
>> -	if (is_sampling_event(event)) {
>> -		dev_dbg(dsu_pmu->pmu.dev, "Can't support sampling events\n");
>> -		return -EOPNOTSUPP;
>> -	}
>> -
>>   	/* We cannot support task bound events */
>>   	if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK) {
>>   		dev_dbg(dsu_pmu->pmu.dev, "Can't support per-task counters\n");
>>   		return -EINVAL;
>>   	}
>>   
>> -	if (has_branch_stack(event)) {
>> -		dev_dbg(dsu_pmu->pmu.dev, "Can't support filtering\n");
>> -		return -EINVAL;
>> -	}
>> -
> 
> I'm assuming that this and the other has_branch_stack() check were
> removed because branch stacks don't actually do anything unless sampling
> is enabled?
> 
> It's a small difference that there is now no error message if you ask
> for branch stacks, but it wouldn't have done anything anyway? I suppose
> this error message was also not applied very consistently across the
> different devices.

Right - the rarity of these checks, plus the fact that in both cases 
here they give a nonsensical debug message that has nothing whatsoever 
to do with the actual failing condition, seems to make it clear that 
they aren't realistically useful.

In general I don't see any good reason for a non-sampling event to be 
picky about the exact type of samples it isn't collecting.

Thanks,
Robin.

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

* Re: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT
  2024-03-12 17:34 ` [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT Robin Murphy
@ 2024-03-13 12:05   ` kernel test robot
  2024-03-13 15:44   ` kernel test robot
  1 sibling, 0 replies; 21+ messages in thread
From: kernel test robot @ 2024-03-13 12:05 UTC (permalink / raw)
  To: Robin Murphy, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon
  Cc: llvm, oe-kbuild-all, Alexander Shishkin, Jiri Olsa, Ian Rogers,
	Adrian Hunter, linux-kernel, linux-arm-kernel, x86,
	linux-perf-users, jialong.yang

Hi Robin,

kernel test robot noticed the following build errors:

[auto build test ERROR on perf-tools-next/perf-tools-next]
[also build test ERROR on perf-tools/perf-tools linus/master v6.8 next-20240313]
[cannot apply to acme/perf/core tip/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Robin-Murphy/perf-alibaba_uncore_drw-Use-correct-CPU-affinity/20240313-013915
base:   https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf-tools-next
patch link:    https://lore.kernel.org/r/0999a39f0a068979dbcc6119380f63d706101b4f.1710257512.git.robin.murphy%40arm.com
patch subject: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT
config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20240313/202403131930.sz1VjXDw-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240313/202403131930.sz1VjXDw-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403131930.sz1VjXDw-lkp@intel.com/

All errors (new ones prefixed by >>):

>> arch/x86/events/core.c:1815:46: error: expected ';' after expression
    1815 |         pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING
         |                                                     ^
         |                                                     ;
   1 error generated.


vim +1815 arch/x86/events/core.c

  1799	
  1800	static void __init pmu_check_apic(void)
  1801	{
  1802		if (boot_cpu_has(X86_FEATURE_APIC))
  1803			return;
  1804	
  1805		x86_pmu.apic = 0;
  1806		pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
  1807		pr_info("no hardware sampling interrupt available.\n");
  1808	
  1809		/*
  1810		 * If we have a PMU initialized but no APIC
  1811		 * interrupts, we cannot sample hardware
  1812		 * events (user-space has to fall back and
  1813		 * sample via a hrtimer based software event):
  1814		 */
> 1815		pmu.capabilities |= PERF_PMU_CAP_NO_SAMPLING
  1816	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 07/10] perf: Define common uncore capabilities
  2024-03-13 11:23   ` James Clark
@ 2024-03-13 12:24     ` Robin Murphy
  0 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-13 12:24 UTC (permalink / raw)
  To: James Clark
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users,
	jialong.yang, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon

On 2024-03-13 11:23 am, James Clark wrote:
> 
> 
> On 12/03/2024 17:34, Robin Murphy wrote:
>> Nearly all uncore/system PMUs share a common set of capbilities,
>> so let's wrap those up in a single macro for ease of use.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   include/linux/perf_event.h | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
>> index b1fd832ed8bf..5d5db122005b 100644
>> --- a/include/linux/perf_event.h
>> +++ b/include/linux/perf_event.h
>> @@ -293,6 +293,9 @@ struct perf_event_pmu_context;
>>   #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
>>   #define PERF_PMU_CAP_NO_COMMON_EVENTS		0x0200
>>   
>> +#define PERF_PMU_UNCORE_CAPS \
>> +(PERF_PMU_CAP_NO_SAMPLING| PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_COMMON_EVENTS)
>> +
> 
> The most minor of nits: missing space before |. There is another one in
> another commit that triggers checkpatch but that line gets deleted anyway.

Bleh, thanks for the catch. And it seems that wasn't the only thing I 
inexplicably managed to mess up in the rename patch either... All fixed 
locally now.

Cheers,
Robin.

> 
>>   struct perf_output_handle;
>>   
>>   #define PMU_NULL_DEV	((void *)(~0UL))

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

* Re: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT
  2024-03-12 17:34 ` [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT Robin Murphy
  2024-03-13 12:05   ` kernel test robot
@ 2024-03-13 15:44   ` kernel test robot
  1 sibling, 0 replies; 21+ messages in thread
From: kernel test robot @ 2024-03-13 15:44 UTC (permalink / raw)
  To: Robin Murphy, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim,
	Mark Rutland, Will Deacon
  Cc: oe-kbuild-all, Alexander Shishkin, Jiri Olsa, Ian Rogers,
	Adrian Hunter, linux-kernel, linux-arm-kernel, x86,
	linux-perf-users, jialong.yang

Hi Robin,

kernel test robot noticed the following build warnings:

[auto build test WARNING on perf-tools-next/perf-tools-next]
[also build test WARNING on perf-tools/perf-tools linus/master v6.8 next-20240313]
[cannot apply to acme/perf/core tip/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Robin-Murphy/perf-alibaba_uncore_drw-Use-correct-CPU-affinity/20240313-013915
base:   https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf-tools-next
patch link:    https://lore.kernel.org/r/0999a39f0a068979dbcc6119380f63d706101b4f.1710257512.git.robin.murphy%40arm.com
patch subject: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT
config: powerpc-allmodconfig (https://download.01.org/0day-ci/archive/20240313/202403132349.Ph0CYSV2-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240313/202403132349.Ph0CYSV2-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403132349.Ph0CYSV2-lkp@intel.com/

All warnings (new ones prefixed by >>):

   arch/powerpc/perf/hv-24x7.c: In function 'hv_24x7_init':
   arch/powerpc/perf/hv-24x7.c:1742:9: error: expected ';' before 'r'
    1742 |         r = create_events_from_catalog(&event_group.attrs,
         |         ^
   arch/powerpc/perf/hv-24x7.c: At top level:
>> arch/powerpc/perf/hv-24x7.c:764:12: warning: 'create_events_from_catalog' defined but not used [-Wunused-function]
     764 | static int create_events_from_catalog(struct attribute ***events_,
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/create_events_from_catalog +764 arch/powerpc/perf/hv-24x7.c

5c5cd7b502595f Cody P Schafer        2015-01-30   763  
7debc970ae7a55 Li Zhong              2015-04-13  @764  static int create_events_from_catalog(struct attribute ***events_,
5c5cd7b502595f Cody P Schafer        2015-01-30   765  				      struct attribute ***event_descs_,
5c5cd7b502595f Cody P Schafer        2015-01-30   766  				      struct attribute ***event_long_descs_)
5c5cd7b502595f Cody P Schafer        2015-01-30   767  {
38d81846106bb1 Thiago Jung Bauermann 2017-06-29   768  	long hret;
5c5cd7b502595f Cody P Schafer        2015-01-30   769  	size_t catalog_len, catalog_page_len, event_entry_count,
5c5cd7b502595f Cody P Schafer        2015-01-30   770  	       event_data_len, event_data_offs,
5c5cd7b502595f Cody P Schafer        2015-01-30   771  	       event_data_bytes, junk_events, event_idx, event_attr_ct, i,
5c5cd7b502595f Cody P Schafer        2015-01-30   772  	       attr_max, event_idx_last, desc_ct, long_desc_ct;
5c5cd7b502595f Cody P Schafer        2015-01-30   773  	ssize_t ct, ev_len;
12bf85a71000af Thiago Jung Bauermann 2017-06-29   774  	uint64_t catalog_version_num;
5c5cd7b502595f Cody P Schafer        2015-01-30   775  	struct attribute **events, **event_descs, **event_long_descs;
5c5cd7b502595f Cody P Schafer        2015-01-30   776  	struct hv_24x7_catalog_page_0 *page_0 =
5c5cd7b502595f Cody P Schafer        2015-01-30   777  		kmem_cache_alloc(hv_page_cache, GFP_KERNEL);
5c5cd7b502595f Cody P Schafer        2015-01-30   778  	void *page = page_0;
5c5cd7b502595f Cody P Schafer        2015-01-30   779  	void *event_data, *end;
5c5cd7b502595f Cody P Schafer        2015-01-30   780  	struct hv_24x7_event_data *event;
5c5cd7b502595f Cody P Schafer        2015-01-30   781  	struct rb_root ev_uniq = RB_ROOT;
7debc970ae7a55 Li Zhong              2015-04-13   782  	int ret = 0;
5c5cd7b502595f Cody P Schafer        2015-01-30   783  
7debc970ae7a55 Li Zhong              2015-04-13   784  	if (!page) {
7debc970ae7a55 Li Zhong              2015-04-13   785  		ret = -ENOMEM;
5c5cd7b502595f Cody P Schafer        2015-01-30   786  		goto e_out;
7debc970ae7a55 Li Zhong              2015-04-13   787  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   788  
5c5cd7b502595f Cody P Schafer        2015-01-30   789  	hret = h_get_24x7_catalog_page(page, 0, 0);
7debc970ae7a55 Li Zhong              2015-04-13   790  	if (hret) {
7debc970ae7a55 Li Zhong              2015-04-13   791  		ret = -EIO;
5c5cd7b502595f Cody P Schafer        2015-01-30   792  		goto e_free;
7debc970ae7a55 Li Zhong              2015-04-13   793  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   794  
5c5cd7b502595f Cody P Schafer        2015-01-30   795  	catalog_version_num = be64_to_cpu(page_0->version);
5c5cd7b502595f Cody P Schafer        2015-01-30   796  	catalog_page_len = be32_to_cpu(page_0->length);
5c5cd7b502595f Cody P Schafer        2015-01-30   797  
5c5cd7b502595f Cody P Schafer        2015-01-30   798  	if (MAX_4K < catalog_page_len) {
5c5cd7b502595f Cody P Schafer        2015-01-30   799  		pr_err("invalid page count: %zu\n", catalog_page_len);
7debc970ae7a55 Li Zhong              2015-04-13   800  		ret = -EIO;
5c5cd7b502595f Cody P Schafer        2015-01-30   801  		goto e_free;
5c5cd7b502595f Cody P Schafer        2015-01-30   802  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   803  
5c5cd7b502595f Cody P Schafer        2015-01-30   804  	catalog_len = catalog_page_len * 4096;
5c5cd7b502595f Cody P Schafer        2015-01-30   805  
5c5cd7b502595f Cody P Schafer        2015-01-30   806  	event_entry_count = be16_to_cpu(page_0->event_entry_count);
5c5cd7b502595f Cody P Schafer        2015-01-30   807  	event_data_offs   = be16_to_cpu(page_0->event_data_offs);
5c5cd7b502595f Cody P Schafer        2015-01-30   808  	event_data_len    = be16_to_cpu(page_0->event_data_len);
5c5cd7b502595f Cody P Schafer        2015-01-30   809  
12bf85a71000af Thiago Jung Bauermann 2017-06-29   810  	pr_devel("cv %llu cl %zu eec %zu edo %zu edl %zu\n",
12bf85a71000af Thiago Jung Bauermann 2017-06-29   811  			catalog_version_num, catalog_len,
5c5cd7b502595f Cody P Schafer        2015-01-30   812  			event_entry_count, event_data_offs, event_data_len);
5c5cd7b502595f Cody P Schafer        2015-01-30   813  
5c5cd7b502595f Cody P Schafer        2015-01-30   814  	if ((MAX_4K < event_data_len)
5c5cd7b502595f Cody P Schafer        2015-01-30   815  			|| (MAX_4K < event_data_offs)
5c5cd7b502595f Cody P Schafer        2015-01-30   816  			|| (MAX_4K - event_data_offs < event_data_len)) {
5c5cd7b502595f Cody P Schafer        2015-01-30   817  		pr_err("invalid event data offs %zu and/or len %zu\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   818  				event_data_offs, event_data_len);
7debc970ae7a55 Li Zhong              2015-04-13   819  		ret = -EIO;
5c5cd7b502595f Cody P Schafer        2015-01-30   820  		goto e_free;
5c5cd7b502595f Cody P Schafer        2015-01-30   821  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   822  
5c5cd7b502595f Cody P Schafer        2015-01-30   823  	if ((event_data_offs + event_data_len) > catalog_page_len) {
5c5cd7b502595f Cody P Schafer        2015-01-30   824  		pr_err("event data %zu-%zu does not fit inside catalog 0-%zu\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   825  				event_data_offs,
5c5cd7b502595f Cody P Schafer        2015-01-30   826  				event_data_offs + event_data_len,
5c5cd7b502595f Cody P Schafer        2015-01-30   827  				catalog_page_len);
7debc970ae7a55 Li Zhong              2015-04-13   828  		ret = -EIO;
5c5cd7b502595f Cody P Schafer        2015-01-30   829  		goto e_free;
5c5cd7b502595f Cody P Schafer        2015-01-30   830  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   831  
8f69dc701aac17 Sukadev Bhattiprolu   2016-02-16   832  	if (SIZE_MAX - 1 < event_entry_count) {
8f69dc701aac17 Sukadev Bhattiprolu   2016-02-16   833  		pr_err("event_entry_count %zu is invalid\n", event_entry_count);
7debc970ae7a55 Li Zhong              2015-04-13   834  		ret = -EIO;
5c5cd7b502595f Cody P Schafer        2015-01-30   835  		goto e_free;
5c5cd7b502595f Cody P Schafer        2015-01-30   836  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   837  
5c5cd7b502595f Cody P Schafer        2015-01-30   838  	event_data_bytes = event_data_len * 4096;
5c5cd7b502595f Cody P Schafer        2015-01-30   839  
5c5cd7b502595f Cody P Schafer        2015-01-30   840  	/*
5c5cd7b502595f Cody P Schafer        2015-01-30   841  	 * event data can span several pages, events can cross between these
5c5cd7b502595f Cody P Schafer        2015-01-30   842  	 * pages. Use vmalloc to make this easier.
5c5cd7b502595f Cody P Schafer        2015-01-30   843  	 */
5c5cd7b502595f Cody P Schafer        2015-01-30   844  	event_data = vmalloc(event_data_bytes);
5c5cd7b502595f Cody P Schafer        2015-01-30   845  	if (!event_data) {
5c5cd7b502595f Cody P Schafer        2015-01-30   846  		pr_err("could not allocate event data\n");
7debc970ae7a55 Li Zhong              2015-04-13   847  		ret = -ENOMEM;
5c5cd7b502595f Cody P Schafer        2015-01-30   848  		goto e_free;
5c5cd7b502595f Cody P Schafer        2015-01-30   849  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   850  
5c5cd7b502595f Cody P Schafer        2015-01-30   851  	end = event_data + event_data_bytes;
5c5cd7b502595f Cody P Schafer        2015-01-30   852  
5c5cd7b502595f Cody P Schafer        2015-01-30   853  	/*
5c5cd7b502595f Cody P Schafer        2015-01-30   854  	 * using vmalloc_to_phys() like this only works if PAGE_SIZE is
5c5cd7b502595f Cody P Schafer        2015-01-30   855  	 * divisible by 4096
5c5cd7b502595f Cody P Schafer        2015-01-30   856  	 */
5c5cd7b502595f Cody P Schafer        2015-01-30   857  	BUILD_BUG_ON(PAGE_SIZE % 4096);
5c5cd7b502595f Cody P Schafer        2015-01-30   858  
5c5cd7b502595f Cody P Schafer        2015-01-30   859  	for (i = 0; i < event_data_len; i++) {
5c5cd7b502595f Cody P Schafer        2015-01-30   860  		hret = h_get_24x7_catalog_page_(
5c5cd7b502595f Cody P Schafer        2015-01-30   861  				vmalloc_to_phys(event_data + i * 4096),
5c5cd7b502595f Cody P Schafer        2015-01-30   862  				catalog_version_num,
5c5cd7b502595f Cody P Schafer        2015-01-30   863  				i + event_data_offs);
5c5cd7b502595f Cody P Schafer        2015-01-30   864  		if (hret) {
12bf85a71000af Thiago Jung Bauermann 2017-06-29   865  			pr_err("Failed to get event data in page %zu: rc=%ld\n",
12bf85a71000af Thiago Jung Bauermann 2017-06-29   866  			       i + event_data_offs, hret);
7debc970ae7a55 Li Zhong              2015-04-13   867  			ret = -EIO;
5c5cd7b502595f Cody P Schafer        2015-01-30   868  			goto e_event_data;
5c5cd7b502595f Cody P Schafer        2015-01-30   869  		}
5c5cd7b502595f Cody P Schafer        2015-01-30   870  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   871  
5c5cd7b502595f Cody P Schafer        2015-01-30   872  	/*
5c5cd7b502595f Cody P Schafer        2015-01-30   873  	 * scan the catalog to determine the number of attributes we need, and
5c5cd7b502595f Cody P Schafer        2015-01-30   874  	 * verify it at the same time.
5c5cd7b502595f Cody P Schafer        2015-01-30   875  	 */
5c5cd7b502595f Cody P Schafer        2015-01-30   876  	for (junk_events = 0, event = event_data, event_idx = 0, attr_max = 0;
5c5cd7b502595f Cody P Schafer        2015-01-30   877  	     ;
5c5cd7b502595f Cody P Schafer        2015-01-30   878  	     event_idx++, event = (void *)event + ev_len) {
5c5cd7b502595f Cody P Schafer        2015-01-30   879  		size_t offset = (void *)event - (void *)event_data;
5c5cd7b502595f Cody P Schafer        2015-01-30   880  		char *name;
5c5cd7b502595f Cody P Schafer        2015-01-30   881  		int nl;
5c5cd7b502595f Cody P Schafer        2015-01-30   882  
5c5cd7b502595f Cody P Schafer        2015-01-30   883  		ev_len = catalog_event_len_validate(event, event_idx,
5c5cd7b502595f Cody P Schafer        2015-01-30   884  						    event_data_bytes,
5c5cd7b502595f Cody P Schafer        2015-01-30   885  						    event_entry_count,
5c5cd7b502595f Cody P Schafer        2015-01-30   886  						    offset, end);
5c5cd7b502595f Cody P Schafer        2015-01-30   887  		if (ev_len < 0)
5c5cd7b502595f Cody P Schafer        2015-01-30   888  			break;
5c5cd7b502595f Cody P Schafer        2015-01-30   889  
5c5cd7b502595f Cody P Schafer        2015-01-30   890  		name = event_name(event, &nl);
5c5cd7b502595f Cody P Schafer        2015-01-30   891  
e5f9d8858612c1 Kajol Jain            2020-12-28   892  		if (ignore_event(name)) {
e5f9d8858612c1 Kajol Jain            2020-12-28   893  			junk_events++;
e5f9d8858612c1 Kajol Jain            2020-12-28   894  			continue;
e5f9d8858612c1 Kajol Jain            2020-12-28   895  		}
5c5cd7b502595f Cody P Schafer        2015-01-30   896  		if (event->event_group_record_len == 0) {
5c5cd7b502595f Cody P Schafer        2015-01-30   897  			pr_devel("invalid event %zu (%.*s): group_record_len == 0, skipping\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   898  					event_idx, nl, name);
5c5cd7b502595f Cody P Schafer        2015-01-30   899  			junk_events++;
5c5cd7b502595f Cody P Schafer        2015-01-30   900  			continue;
5c5cd7b502595f Cody P Schafer        2015-01-30   901  		}
5c5cd7b502595f Cody P Schafer        2015-01-30   902  
5c5cd7b502595f Cody P Schafer        2015-01-30   903  		if (!catalog_entry_domain_is_valid(event->domain)) {
5c5cd7b502595f Cody P Schafer        2015-01-30   904  			pr_info("event %zu (%.*s) has invalid domain %d\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   905  					event_idx, nl, name, event->domain);
5c5cd7b502595f Cody P Schafer        2015-01-30   906  			junk_events++;
5c5cd7b502595f Cody P Schafer        2015-01-30   907  			continue;
5c5cd7b502595f Cody P Schafer        2015-01-30   908  		}
5c5cd7b502595f Cody P Schafer        2015-01-30   909  
8f69dc701aac17 Sukadev Bhattiprolu   2016-02-16   910  		attr_max++;
5c5cd7b502595f Cody P Schafer        2015-01-30   911  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   912  
5c5cd7b502595f Cody P Schafer        2015-01-30   913  	event_idx_last = event_idx;
5c5cd7b502595f Cody P Schafer        2015-01-30   914  	if (event_idx_last != event_entry_count)
5c5cd7b502595f Cody P Schafer        2015-01-30   915  		pr_warn("event buffer ended before listed # of events were parsed (got %zu, wanted %zu, junk %zu)\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   916  				event_idx_last, event_entry_count, junk_events);
5c5cd7b502595f Cody P Schafer        2015-01-30   917  
5c5cd7b502595f Cody P Schafer        2015-01-30   918  	events = kmalloc_array(attr_max + 1, sizeof(*events), GFP_KERNEL);
7debc970ae7a55 Li Zhong              2015-04-13   919  	if (!events) {
7debc970ae7a55 Li Zhong              2015-04-13   920  		ret = -ENOMEM;
5c5cd7b502595f Cody P Schafer        2015-01-30   921  		goto e_event_data;
7debc970ae7a55 Li Zhong              2015-04-13   922  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   923  
5c5cd7b502595f Cody P Schafer        2015-01-30   924  	event_descs = kmalloc_array(event_idx + 1, sizeof(*event_descs),
5c5cd7b502595f Cody P Schafer        2015-01-30   925  				GFP_KERNEL);
7debc970ae7a55 Li Zhong              2015-04-13   926  	if (!event_descs) {
7debc970ae7a55 Li Zhong              2015-04-13   927  		ret = -ENOMEM;
5c5cd7b502595f Cody P Schafer        2015-01-30   928  		goto e_event_attrs;
7debc970ae7a55 Li Zhong              2015-04-13   929  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   930  
5c5cd7b502595f Cody P Schafer        2015-01-30   931  	event_long_descs = kmalloc_array(event_idx + 1,
5c5cd7b502595f Cody P Schafer        2015-01-30   932  			sizeof(*event_long_descs), GFP_KERNEL);
7debc970ae7a55 Li Zhong              2015-04-13   933  	if (!event_long_descs) {
7debc970ae7a55 Li Zhong              2015-04-13   934  		ret = -ENOMEM;
5c5cd7b502595f Cody P Schafer        2015-01-30   935  		goto e_event_descs;
7debc970ae7a55 Li Zhong              2015-04-13   936  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   937  
5c5cd7b502595f Cody P Schafer        2015-01-30   938  	/* Iterate over the catalog filling in the attribute vector */
5c5cd7b502595f Cody P Schafer        2015-01-30   939  	for (junk_events = 0, event_attr_ct = 0, desc_ct = 0, long_desc_ct = 0,
5c5cd7b502595f Cody P Schafer        2015-01-30   940  				event = event_data, event_idx = 0;
5c5cd7b502595f Cody P Schafer        2015-01-30   941  			event_idx < event_idx_last;
5c5cd7b502595f Cody P Schafer        2015-01-30   942  			event_idx++, ev_len = be16_to_cpu(event->length),
5c5cd7b502595f Cody P Schafer        2015-01-30   943  				event = (void *)event + ev_len) {
5c5cd7b502595f Cody P Schafer        2015-01-30   944  		char *name;
5c5cd7b502595f Cody P Schafer        2015-01-30   945  		int nl;
5c5cd7b502595f Cody P Schafer        2015-01-30   946  		int nonce;
5c5cd7b502595f Cody P Schafer        2015-01-30   947  		/*
5c5cd7b502595f Cody P Schafer        2015-01-30   948  		 * these are the only "bad" events that are intermixed and that
5c5cd7b502595f Cody P Schafer        2015-01-30   949  		 * we can ignore without issue. make sure to skip them here
5c5cd7b502595f Cody P Schafer        2015-01-30   950  		 */
5c5cd7b502595f Cody P Schafer        2015-01-30   951  		if (event->event_group_record_len == 0)
5c5cd7b502595f Cody P Schafer        2015-01-30   952  			continue;
5c5cd7b502595f Cody P Schafer        2015-01-30   953  		if (!catalog_entry_domain_is_valid(event->domain))
5c5cd7b502595f Cody P Schafer        2015-01-30   954  			continue;
5c5cd7b502595f Cody P Schafer        2015-01-30   955  
5c5cd7b502595f Cody P Schafer        2015-01-30   956  		name  = event_name(event, &nl);
e5f9d8858612c1 Kajol Jain            2020-12-28   957  		if (ignore_event(name))
e5f9d8858612c1 Kajol Jain            2020-12-28   958  			continue;
e5f9d8858612c1 Kajol Jain            2020-12-28   959  
5c5cd7b502595f Cody P Schafer        2015-01-30   960  		nonce = event_uniq_add(&ev_uniq, name, nl, event->domain);
5c5cd7b502595f Cody P Schafer        2015-01-30   961  		ct    = event_data_to_attrs(event_idx, events + event_attr_ct,
5c5cd7b502595f Cody P Schafer        2015-01-30   962  					    event, nonce);
8f69dc701aac17 Sukadev Bhattiprolu   2016-02-16   963  		if (ct < 0) {
5c5cd7b502595f Cody P Schafer        2015-01-30   964  			pr_warn("event %zu (%.*s) creation failure, skipping\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   965  				event_idx, nl, name);
5c5cd7b502595f Cody P Schafer        2015-01-30   966  			junk_events++;
5c5cd7b502595f Cody P Schafer        2015-01-30   967  		} else {
8f69dc701aac17 Sukadev Bhattiprolu   2016-02-16   968  			event_attr_ct++;
5c5cd7b502595f Cody P Schafer        2015-01-30   969  			event_descs[desc_ct] = event_to_desc_attr(event, nonce);
5c5cd7b502595f Cody P Schafer        2015-01-30   970  			if (event_descs[desc_ct])
5c5cd7b502595f Cody P Schafer        2015-01-30   971  				desc_ct++;
5c5cd7b502595f Cody P Schafer        2015-01-30   972  			event_long_descs[long_desc_ct] =
5c5cd7b502595f Cody P Schafer        2015-01-30   973  					event_to_long_desc_attr(event, nonce);
5c5cd7b502595f Cody P Schafer        2015-01-30   974  			if (event_long_descs[long_desc_ct])
5c5cd7b502595f Cody P Schafer        2015-01-30   975  				long_desc_ct++;
5c5cd7b502595f Cody P Schafer        2015-01-30   976  		}
5c5cd7b502595f Cody P Schafer        2015-01-30   977  	}
5c5cd7b502595f Cody P Schafer        2015-01-30   978  
5c5cd7b502595f Cody P Schafer        2015-01-30   979  	pr_info("read %zu catalog entries, created %zu event attrs (%zu failures), %zu descs\n",
5c5cd7b502595f Cody P Schafer        2015-01-30   980  			event_idx, event_attr_ct, junk_events, desc_ct);
5c5cd7b502595f Cody P Schafer        2015-01-30   981  
5c5cd7b502595f Cody P Schafer        2015-01-30   982  	events[event_attr_ct] = NULL;
5c5cd7b502595f Cody P Schafer        2015-01-30   983  	event_descs[desc_ct] = NULL;
5c5cd7b502595f Cody P Schafer        2015-01-30   984  	event_long_descs[long_desc_ct] = NULL;
5c5cd7b502595f Cody P Schafer        2015-01-30   985  
5c5cd7b502595f Cody P Schafer        2015-01-30   986  	event_uniq_destroy(&ev_uniq);
5c5cd7b502595f Cody P Schafer        2015-01-30   987  	vfree(event_data);
5c5cd7b502595f Cody P Schafer        2015-01-30   988  	kmem_cache_free(hv_page_cache, page);
5c5cd7b502595f Cody P Schafer        2015-01-30   989  
5c5cd7b502595f Cody P Schafer        2015-01-30   990  	*events_ = events;
5c5cd7b502595f Cody P Schafer        2015-01-30   991  	*event_descs_ = event_descs;
5c5cd7b502595f Cody P Schafer        2015-01-30   992  	*event_long_descs_ = event_long_descs;
7debc970ae7a55 Li Zhong              2015-04-13   993  	return 0;
5c5cd7b502595f Cody P Schafer        2015-01-30   994  
5c5cd7b502595f Cody P Schafer        2015-01-30   995  e_event_descs:
5c5cd7b502595f Cody P Schafer        2015-01-30   996  	kfree(event_descs);
5c5cd7b502595f Cody P Schafer        2015-01-30   997  e_event_attrs:
5c5cd7b502595f Cody P Schafer        2015-01-30   998  	kfree(events);
5c5cd7b502595f Cody P Schafer        2015-01-30   999  e_event_data:
5c5cd7b502595f Cody P Schafer        2015-01-30  1000  	vfree(event_data);
5c5cd7b502595f Cody P Schafer        2015-01-30  1001  e_free:
5c5cd7b502595f Cody P Schafer        2015-01-30  1002  	kmem_cache_free(hv_page_cache, page);
5c5cd7b502595f Cody P Schafer        2015-01-30  1003  e_out:
5c5cd7b502595f Cody P Schafer        2015-01-30  1004  	*events_ = NULL;
5c5cd7b502595f Cody P Schafer        2015-01-30  1005  	*event_descs_ = NULL;
5c5cd7b502595f Cody P Schafer        2015-01-30  1006  	*event_long_descs_ = NULL;
7debc970ae7a55 Li Zhong              2015-04-13  1007  	return ret;
5c5cd7b502595f Cody P Schafer        2015-01-30  1008  }
5c5cd7b502595f Cody P Schafer        2015-01-30  1009  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 02/10] perf: Add capability for common event support
  2024-03-12 17:34 ` [PATCH 02/10] perf: Add capability for common event support Robin Murphy
@ 2024-03-14  8:09   ` Yang Jialong 杨佳龙
  2024-03-14 12:34     ` Robin Murphy
  0 siblings, 1 reply; 21+ messages in thread
From: Yang Jialong 杨佳龙 @ 2024-03-14  8:09 UTC (permalink / raw)
  To: Robin Murphy, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland, Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users



在 2024/3/13 1:34, Robin Murphy 写道:
> Many PMUs do not support common hardware/cache/etc. events and only
> handle their own PMU-specific events. Since this only depends on
> matching the event and PMU types, it's a prime candidate for a core
> capability to save more event_init boilerplate in drivers.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>   include/linux/perf_event.h | 1 +
>   kernel/events/core.c       | 5 +++++
>   2 files changed, 6 insertions(+)
> 
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index d2a15c0c6f8a..983201f21dd2 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -291,6 +291,7 @@ struct perf_event_pmu_context;
>   #define PERF_PMU_CAP_NO_EXCLUDE			0x0040
>   #define PERF_PMU_CAP_AUX_OUTPUT			0x0080
>   #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
> +#define PERF_PMU_CAP_NO_COMMON_EVENTS		0x0200
>   
>   struct perf_output_handle;
>   
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index f0f0f71213a1..7ad80826c218 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -11649,6 +11649,11 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
>   	struct perf_event_context *ctx = NULL;
>   	int ret;
>   
> +	/* Short-circuit if we know the PMU won't want this event */
> +	if (pmu->capabilities & PERF_PMU_CAP_NO_COMMON_EVENTS &&
> +	    event->attr.type != pmu->type)
> +		return -ENOENT;
> +

         /*
          * PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
          * are often aliases for PERF_TYPE_RAW.
          */
         type = event->attr.type;
         if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE) {
                 type = event->attr.config >> PERF_PMU_TYPE_SHIFT;
                 if (!type) {
                         type = PERF_TYPE_RAW;
                 } else {
                         extended_type = true;
                         event->attr.config &= PERF_HW_EVENT_MASK;
                 }
         }

again:
         rcu_read_lock();
         pmu = idr_find(&pmu_idr, type);
         rcu_read_unlock();
         if (pmu) {
Above code tells me it's possible that 'pmu->type != event->attr.type' 
is true when event->attr.type equals to PERF_TYPE_HARDWARE or 
PERF_TYPE_HW_CACHE, and pmu->type should equal to event->attr.config >> 
PERF_PMU_TYPE_SHIFT.

We find the target pmu by event->attr.config >> PERF_PMU_TYPE_SHIFT.

Code added discard this option.

And code tells me that no try. Target PMU is doubtless.




>   	if (!try_module_get(pmu->module))
>   		return -ENODEV;
>   


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

* Re: [PATCH 02/10] perf: Add capability for common event support
  2024-03-14  8:09   ` Yang Jialong 杨佳龙
@ 2024-03-14 12:34     ` Robin Murphy
  0 siblings, 0 replies; 21+ messages in thread
From: Robin Murphy @ 2024-03-14 12:34 UTC (permalink / raw)
  To: Yang Jialong 杨佳龙, Peter Zijlstra,
	Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
	Will Deacon
  Cc: Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	linux-kernel, linux-arm-kernel, x86, linux-perf-users

On 2024-03-14 8:09 am, Yang Jialong 杨佳龙 wrote:
> 
> 
> 在 2024/3/13 1:34, Robin Murphy 写道:
>> Many PMUs do not support common hardware/cache/etc. events and only
>> handle their own PMU-specific events. Since this only depends on
>> matching the event and PMU types, it's a prime candidate for a core
>> capability to save more event_init boilerplate in drivers.
>>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   include/linux/perf_event.h | 1 +
>>   kernel/events/core.c       | 5 +++++
>>   2 files changed, 6 insertions(+)
>>
>> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
>> index d2a15c0c6f8a..983201f21dd2 100644
>> --- a/include/linux/perf_event.h
>> +++ b/include/linux/perf_event.h
>> @@ -291,6 +291,7 @@ struct perf_event_pmu_context;
>>   #define PERF_PMU_CAP_NO_EXCLUDE            0x0040
>>   #define PERF_PMU_CAP_AUX_OUTPUT            0x0080
>>   #define PERF_PMU_CAP_EXTENDED_HW_TYPE        0x0100
>> +#define PERF_PMU_CAP_NO_COMMON_EVENTS        0x0200
>>   struct perf_output_handle;
>> diff --git a/kernel/events/core.c b/kernel/events/core.c
>> index f0f0f71213a1..7ad80826c218 100644
>> --- a/kernel/events/core.c
>> +++ b/kernel/events/core.c
>> @@ -11649,6 +11649,11 @@ static int perf_try_init_event(struct pmu 
>> *pmu, struct perf_event *event)
>>       struct perf_event_context *ctx = NULL;
>>       int ret;
>> +    /* Short-circuit if we know the PMU won't want this event */
>> +    if (pmu->capabilities & PERF_PMU_CAP_NO_COMMON_EVENTS &&
>> +        event->attr.type != pmu->type)
>> +        return -ENOENT;
>> +
> 
>          /*
>           * PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
>           * are often aliases for PERF_TYPE_RAW.
>           */
>          type = event->attr.type;
>          if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE) {
>                  type = event->attr.config >> PERF_PMU_TYPE_SHIFT;
>                  if (!type) {
>                          type = PERF_TYPE_RAW;
>                  } else {
>                          extended_type = true;
>                          event->attr.config &= PERF_HW_EVENT_MASK;
>                  }
>          }
> 
> again:
>          rcu_read_lock();
>          pmu = idr_find(&pmu_idr, type);
>          rcu_read_unlock();
>          if (pmu) {
> Above code tells me it's possible that 'pmu->type != event->attr.type' 
> is true when event->attr.type equals to PERF_TYPE_HARDWARE or 
> PERF_TYPE_HW_CACHE, and pmu->type should equal to event->attr.config >> 
> PERF_PMU_TYPE_SHIFT.
> 
> We find the target pmu by event->attr.config >> PERF_PMU_TYPE_SHIFT.

And if that PMU doesn't actually support PERF_TYPE_HARDWARE or 
PERF_TYPE_HW_CACHE then it would reject the event, if the very next 
lines didn't already do that:

	if (event->attr.type != type && type != PERF_TYPE_RAW &&
	    !(pmu->capabilities & PERF_PMU_CAP_EXTENDED_HW_TYPE))
		goto fail;

Either way it should be clear that there's no change of functionality 
here since the flow into perf_try_init_event() itself is untouched.

> Code added discard this option.

It would already be nonsensical for a driver to advertise 
PERF_PMU_CAP_EXTENDED_HW_TYPE to say it supports extended hardware 
events, but then reject all hardware events with a "event->attr.type != 
pmu->type" check in its event_init. Reworking the latter condition into 
PERF_PMU_CAP_NO_COMMON_EVENTS doesn't change that.

Thanks,
Robin.

> 
> And code tells me that no try. Target PMU is doubtless.
> 
> 
> 
> 
>>       if (!try_module_get(pmu->module))
>>           return -ENODEV;
> 

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

* Re: [PATCH 10/10] ARM: Use common uncore PMU capabilities
  2024-03-12 17:34 ` [PATCH 10/10] ARM: " Robin Murphy
@ 2024-03-30 14:59   ` Shawn Guo
  0 siblings, 0 replies; 21+ messages in thread
From: Shawn Guo @ 2024-03-30 14:59 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Will Deacon, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, linux-kernel,
	linux-arm-kernel, x86, linux-perf-users, jialong.yang,
	Russell King, Shawn Guo, Sascha Hauer

On Tue, Mar 12, 2024 at 05:34:12PM +0000, Robin Murphy wrote:
> Switch the ARM system PMU drivers over to the new common capabilities,
> allowing to remove all the checks that perf core now takes care of.
> 
> CC: Russell King <linux@armlinux.org.uk>
> CC: Shawn Guo <shawnguo@kernel.org>
> CC: Sascha Hauer <s.hauer@pengutronix.de>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  arch/arm/mach-imx/mmdc.c     | 16 +---------------

Acked-by: Shawn Guo <shawnguo@kernel.org>

>  arch/arm/mm/cache-l2x0-pmu.c | 12 +-----------
>  2 files changed, 2 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
> index 444a7eaa320c..806ab6675b37 100644
> --- a/arch/arm/mach-imx/mmdc.c
> +++ b/arch/arm/mach-imx/mmdc.c
> @@ -280,20 +280,6 @@ static int mmdc_pmu_event_init(struct perf_event *event)
>  	struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
>  	int cfg = event->attr.config;
>  
> -	if (event->attr.type != event->pmu->type)
> -		return -ENOENT;
> -
> -	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
> -		return -EOPNOTSUPP;
> -
> -	if (event->cpu < 0) {
> -		dev_warn(pmu_mmdc->dev, "Can't provide per-task data!\n");
> -		return -EOPNOTSUPP;
> -	}
> -
> -	if (event->attr.sample_period)
> -		return -EINVAL;
> -
>  	if (cfg < 0 || cfg >= MMDC_NUM_COUNTERS)
>  		return -EINVAL;
>  
> @@ -445,7 +431,7 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
>  			.start          = mmdc_pmu_event_start,
>  			.stop           = mmdc_pmu_event_stop,
>  			.read           = mmdc_pmu_event_update,
> -			.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
> +			.capabilities	= PERF_PMU_UNCORE_CAPS,
>  		},
>  		.mmdc_base = mmdc_base,
>  		.dev = dev,
> diff --git a/arch/arm/mm/cache-l2x0-pmu.c b/arch/arm/mm/cache-l2x0-pmu.c
> index 993fefdc167a..a2567d953fdb 100644
> --- a/arch/arm/mm/cache-l2x0-pmu.c
> +++ b/arch/arm/mm/cache-l2x0-pmu.c
> @@ -295,16 +295,6 @@ static int l2x0_pmu_event_init(struct perf_event *event)
>  {
>  	struct hw_perf_event *hw = &event->hw;
>  
> -	if (event->attr.type != l2x0_pmu->type)
> -		return -ENOENT;
> -
> -	if (is_sampling_event(event) ||
> -	    event->attach_state & PERF_ATTACH_TASK)
> -		return -EINVAL;
> -
> -	if (event->cpu < 0)
> -		return -EINVAL;
> -
>  	if (event->attr.config & ~L2X0_EVENT_CNT_CFG_SRC_MASK)
>  		return -EINVAL;
>  
> @@ -524,7 +514,7 @@ static __init int l2x0_pmu_init(void)
>  		.del = l2x0_pmu_event_del,
>  		.event_init = l2x0_pmu_event_init,
>  		.attr_groups = l2x0_pmu_attr_groups,
> -		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> +		.capabilities = PERF_PMU_UNCORE_CAPS,
>  	};
>  
>  	l2x0_pmu_reset();
> -- 
> 2.39.2.101.g768bb238c484.dirty
> 


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

end of thread, other threads:[~2024-03-30 15:01 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-12 17:34 [PATCH 00/10] perf: Clean up common uncore boilerplate Robin Murphy
2024-03-12 17:34 ` [PATCH 01/10] perf/alibaba_uncore_drw: Use correct CPU affinity Robin Murphy
2024-03-12 17:34 ` [PATCH 02/10] perf: Add capability for common event support Robin Murphy
2024-03-14  8:09   ` Yang Jialong 杨佳龙
2024-03-14 12:34     ` Robin Murphy
2024-03-12 17:34 ` [PATCH 03/10] drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS Robin Murphy
2024-03-12 17:34 ` [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT Robin Murphy
2024-03-13 12:05   ` kernel test robot
2024-03-13 15:44   ` kernel test robot
2024-03-12 17:34 ` [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently Robin Murphy
2024-03-13 11:11   ` James Clark
2024-03-13 12:02     ` Robin Murphy
2024-03-12 17:34 ` [PATCH 06/10] drivers/perf: Clean up redundant per-task checks Robin Murphy
2024-03-12 17:34 ` [PATCH 07/10] perf: Define common uncore capabilities Robin Murphy
2024-03-13 11:23   ` James Clark
2024-03-13 12:24     ` Robin Murphy
2024-03-12 17:34 ` [PATCH 08/10] drivers/perf: Use " Robin Murphy
2024-03-12 17:34 ` [PATCH 09/10] x86: Use common uncore PMU capabilities Robin Murphy
2024-03-12 17:34 ` [PATCH 10/10] ARM: " Robin Murphy
2024-03-30 14:59   ` Shawn Guo
2024-03-13 11:26 ` [PATCH 00/10] perf: Clean up common uncore boilerplate James Clark

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).