From: "Johnny.Fan" <johnny.fan@cixtech.com>
To: will@kernel.org, mark.rutland@arm.com
Cc: suzuki.poulose@arm.com, leo.yan@arm.com, jeremy.linton@arm.com,
maz@kernel.org, mike.leach@arm.com, james.clark@linaro.org,
alexander.shishkin@linux.intel.com, coresight@lists.linaro.org,
linux-arm-kernel@lists.infradead.org,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
cix-kernel-upstream@cixtech.com, jie.fu@cixtech.com,
bob.zhang@cixtech.com, "Johnny.Fan" <Johnny.Fan@cixtech.com>,
Fugang Duan <fugang.duan@cixtech.com>
Subject: [PATCH v3 1/2] perf: arm_pmu: Accept a per-device CPU mask from platform data
Date: Mon, 2 Nov 2026 16:41:51 +0800 [thread overview]
Message-ID: <20261102084153.3975282-2-johnny.fan@cixtech.com> (raw)
In-Reply-To: <20261102084153.3975282-1-johnny.fan@cixtech.com>
From: "Johnny.Fan" <Johnny.Fan@cixtech.com>
Synthetic platform devices created from ACPI data have no fwnode, so
platform_get_irq_affinity() cannot tell which CPUs implement the
feature and falls back to cpu_possible_mask.
Add an optional CPU mask to the platform data and make both the SPE and
the TRBE drivers prefer it over the firmware-described IRQ affinity.
Device tree devices have no platform data and keep using the affinity.
TRBE must also pass a stable copy of the mask to
request_percpu_irq_affinity(), because supported_cpus is pruned as CPUs
are probed, while the IRQ action keeps a pointer to the mask.
This is a preparatory change: no ACPI device carries platform data yet,
so behaviour is unchanged.
Signed-off-by: Johnny.Fan <Johnny.Fan@cixtech.com>
Reviewed-by: Fugang Duan <fugang.duan@cixtech.com>
---
drivers/hwtracing/coresight/coresight-trbe.c | 22 +++++++++++++++++---
drivers/perf/arm_spe_pmu.c | 10 ++++++++-
include/linux/perf/arm_pmu.h | 10 +++++++++
3 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index c7cbca45f2de..0c4bc8fbcaf3 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -158,6 +158,7 @@ struct trbe_drvdata {
struct hlist_node hotplug_node;
int irq;
cpumask_t supported_cpus;
+ cpumask_t irq_affinity;
enum cpuhp_state trbe_online;
struct platform_device *pdev;
};
@@ -1533,6 +1534,8 @@ static void arm_trbe_remove_cpuhp(struct trbe_drvdata *drvdata)
static int arm_trbe_probe_irq(struct platform_device *pdev,
struct trbe_drvdata *drvdata)
{
+ const struct arm_pmu_acpi_dev_data *acpi_data =
+ dev_get_platdata(&pdev->dev);
const struct cpumask *affinity;
int ret;
@@ -1547,14 +1550,27 @@ static int arm_trbe_probe_irq(struct platform_device *pdev,
return -EINVAL;
}
- cpumask_copy(&drvdata->supported_cpus, affinity);
+ /*
+ * The ACPI path has no fwnode describing which CPUs implement TRBE,
+ * so it passes the mask explicitly. DT devices still use the
+ * firmware-described IRQ affinity.
+ */
+ cpumask_copy(&drvdata->supported_cpus,
+ acpi_data ? &acpi_data->cpus : affinity);
+
+ /*
+ * supported_cpus gets pruned as CPUs are probed, so keep a stable
+ * copy for the IRQ action.
+ */
+ cpumask_copy(&drvdata->irq_affinity, &drvdata->supported_cpus);
drvdata->handle = alloc_percpu(struct perf_output_handle *);
if (!drvdata->handle)
return -ENOMEM;
- ret = request_percpu_irq_affinity(drvdata->irq, arm_trbe_irq_handler, DRVNAME,
- affinity, drvdata->handle);
+ ret = request_percpu_irq_affinity(drvdata->irq, arm_trbe_irq_handler,
+ DRVNAME, &drvdata->irq_affinity,
+ drvdata->handle);
if (ret) {
free_percpu(drvdata->handle);
return ret;
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index b70f3fedf028..712b7f187301 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -1330,6 +1330,8 @@ static void arm_spe_pmu_dev_teardown(struct arm_spe_pmu *spe_pmu)
static int arm_spe_pmu_irq_probe(struct arm_spe_pmu *spe_pmu)
{
struct platform_device *pdev = spe_pmu->pdev;
+ const struct arm_pmu_acpi_dev_data *acpi_data =
+ dev_get_platdata(&pdev->dev);
const struct cpumask *affinity;
int irq;
@@ -1342,7 +1344,13 @@ static int arm_spe_pmu_irq_probe(struct arm_spe_pmu *spe_pmu)
return -EINVAL;
}
- cpumask_copy(&spe_pmu->supported_cpus, affinity);
+ /*
+ * The ACPI path has no fwnode describing which CPUs implement SPE,
+ * so it passes the mask explicitly. DT devices still use the
+ * firmware-described IRQ affinity.
+ */
+ cpumask_copy(&spe_pmu->supported_cpus,
+ acpi_data ? &acpi_data->cpus : affinity);
spe_pmu->irq = irq;
return 0;
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 02d2c7f45b52..7f1c03c55025 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -8,6 +8,7 @@
#ifndef __ARM_PMU_H__
#define __ARM_PMU_H__
+#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
@@ -199,6 +200,15 @@ void armpmu_free_irq(struct arm_pmu * __percpu *armpmu, int irq, int cpu);
#define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
#define ARMV8_TRBE_PDEV_NAME "arm,trbe"
+/*
+ * Per-device CPU mask passed by the ACPI MADT walk. The synthetic
+ * platform devices have no fwnode, so the IRQ affinity cannot describe
+ * which CPUs actually implement the feature.
+ */
+struct arm_pmu_acpi_dev_data {
+ struct cpumask cpus;
+};
+
/* Why does everything I do descend into this? */
#define __GEN_PMU_FORMAT_ATTR(cfg, lo, hi) \
(lo) == (hi) ? #cfg ":" #lo "\n" : #cfg ":" #lo "-" #hi
--
2.55.0
next prev parent reply other threads:[~2026-11-02 8:41 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 8:41 [PATCH v3 0/2] perf: arm_spe: Support heterogeneous ACPI systems Johnny.Fan
2026-11-02 8:41 ` Johnny.Fan [this message]
2026-11-02 8:41 ` [PATCH v3 2/2] perf: arm_pmu_acpi: " Johnny.Fan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261102084153.3975282-2-johnny.fan@cixtech.com \
--to=johnny.fan@cixtech.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=bob.zhang@cixtech.com \
--cc=cix-kernel-upstream@cixtech.com \
--cc=coresight@lists.linaro.org \
--cc=fugang.duan@cixtech.com \
--cc=james.clark@linaro.org \
--cc=jeremy.linton@arm.com \
--cc=jie.fu@cixtech.com \
--cc=leo.yan@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=mike.leach@arm.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®