2024-03-12 17:34:36

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 00/10] perf: Clean up common uncore boilerplate

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



2024-03-12 17:35:04

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 02/10] perf: Add capability for common event support

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 <[email protected]>
---
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


2024-03-12 17:35:26

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT

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 <[email protected]>
---
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


2024-03-12 17:35:48

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently

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 <[email protected]>
---
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


2024-03-12 17:35:58

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 06/10] drivers/perf: Clean up redundant per-task checks

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 <[email protected]>
---
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


2024-03-12 17:36:33

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 08/10] drivers/perf: Use common uncore capabilities

Now that we've ratified it, adopt PERF_PMU_UNCORE_CAPS.

Signed-off-by: Robin Murphy <[email protected]>
---
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


2024-03-12 17:36:46

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 09/10] x86: Use common uncore PMU capabilities

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 <[email protected]>
CC: Borislav Petkov <[email protected]>
CC: Dave Hansen <[email protected]>
Signed-off-by: Robin Murphy <[email protected]>
---
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


2024-03-12 17:37:00

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 10/10] ARM: Use common uncore PMU capabilities

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 <[email protected]>
CC: Shawn Guo <[email protected]>
CC: Sascha Hauer <[email protected]>
Signed-off-by: Robin Murphy <[email protected]>
---
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


2024-03-12 17:38:30

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 01/10] perf/alibaba_uncore_drw: Use correct CPU affinity

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 <[email protected]>
Fixes: cf7b61073e45 ("drivers/perf: add DDR Sub-System Driveway PMU driver for Yitian 710 SoC")
Signed-off-by: Robin Murphy <[email protected]>
---
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


2024-03-12 17:41:38

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 03/10] drivers/perf: Use PERF_PMU_CAP_NO_COMMON_EVENTS

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 <[email protected]>
---
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


2024-03-12 17:42:44

by Robin Murphy

[permalink] [raw]
Subject: [PATCH 07/10] perf: Define common uncore capabilities

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 <[email protected]>
---
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


2024-03-13 11:15:55

by James Clark

[permalink] [raw]
Subject: Re: [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently



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 <[email protected]>
> ---
> 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


2024-03-13 11:23:26

by James Clark

[permalink] [raw]
Subject: Re: [PATCH 07/10] perf: Define common uncore capabilities



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 <[email protected]>
> ---
> 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))

2024-03-13 11:27:23

by James Clark

[permalink] [raw]
Subject: Re: [PATCH 00/10] perf: Clean up common uncore boilerplate



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 <[email protected]>

> 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(-)
>

2024-03-13 12:04:57

by Robin Murphy

[permalink] [raw]
Subject: Re: [PATCH 05/10] drivers/perf: Use PERF_PMU_CAP_NO_SAMPLING consistently

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 <[email protected]>
>> ---
>> 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.

2024-03-13 12:17:07

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT

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/[email protected]/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/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

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

2024-03-13 12:24:47

by Robin Murphy

[permalink] [raw]
Subject: Re: [PATCH 07/10] perf: Define common uncore capabilities

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 <[email protected]>
>> ---
>> 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))

2024-03-13 15:45:17

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 04/10] perf: Rename PERF_PMU_CAP_NO_INTERRUPT

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/[email protected]/config)
compiler: powerpc64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240313/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

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

2024-03-14 08:11:09

by Yang Jialong 杨佳龙

[permalink] [raw]
Subject: Re: [PATCH 02/10] perf: Add capability for common event support



在 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 <[email protected]>
> ---
> 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;
>


2024-03-14 12:42:09

by Robin Murphy

[permalink] [raw]
Subject: Re: [PATCH 02/10] perf: Add capability for common event support

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 <[email protected]>
>> ---
>>   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;
>

2024-03-30 15:02:48

by Shawn Guo

[permalink] [raw]
Subject: Re: [PATCH 10/10] ARM: Use common uncore PMU capabilities

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 <[email protected]>
> CC: Shawn Guo <[email protected]>
> CC: Sascha Hauer <[email protected]>
> Signed-off-by: Robin Murphy <[email protected]>
> ---
> arch/arm/mach-imx/mmdc.c | 16 +---------------

Acked-by: Shawn Guo <[email protected]>

> 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
>