From: Heiko Carstens <hca@linux.ibm.com>
To: Thomas Richter <tmricht@linux.ibm.com>
Cc: linux-s390@vger.kernel.org,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Jan Polensky <japo@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>,
Sumanth Korikkar <sumanthk@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>
Subject: Re: [PATCH] s390/cpum_cf: Handle CPU hotplug add and delete
Date: Sun, 9 Aug 2026 20:25:36 +0200 [thread overview]
Message-ID: <20260809182536.21067B5a-hca@linux.ibm.com> (raw)
In-Reply-To: <20260806131131.2073914-1-tmricht@linux.ibm.com>
On Thu, Aug 06, 2026 at 03:11:31PM +0200, Thomas Richter wrote:
> The command 'perf stat -e cycles -- <command>' crashes the kernel
> when CPUs are hotplug added during that run.
>
> Root cause is the allocation of struct cpu_cf_events at first
> event initialization. The allocation is dynamic and the first
> event that has task context creates such a structure for
> each online CPU. This is not sufficient. CPUs may be offline
> during event creation and can be set online during the
> perf run time. For example commands
...
> The issue arises only in per-task context when the CPUMF facility is
> used and the scheduler picks a random CPU for such a process to run on.
> The scheduler enables the CPUMF infrastructure via PMU callback
> functions pmu::add() and pmu::del().
> Now count all per-task processes currently running and active.
> When a CPU is hotplug added, check for running per-task context
> processes. If one or more are active, install the CPUMF infrastructure
> on that new CPU. This ensures the infrastructure is available when
> new CPU is selected to run the per-task context process.
Wouldn't it be easier to add another cpu hotplug handler which is called while
the new / going cpu is offline? That is allocating and freeing of per-cpu data
structures is done on a different CPU. It looks like this would solve also a
couple of the other Sashiko reports about life time.
_Something_ like the below. Completely untested and might be completely
broken, however the implementation looks much simpler, and you don't need to
sprinkle NULL checks everywhere.
---
arch/s390/kernel/perf_cpum_cf.c | 40 +++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
index 2076ac22e2c4..c88ca94b9ec4 100644
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -110,6 +110,7 @@ struct cpu_cf_ptr {
static struct cpu_cf_root { /* Anchor to per CPU data */
refcount_t refcnt; /* Overall active events */
+ refcount_t syswide_refcnt; /* System wide active events */
struct cpu_cf_ptr __percpu *cfptr;
} cpu_cf_root;
@@ -293,6 +294,7 @@ static int cpum_cf_alloc(int cpu)
if (cpu == -1) {
if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
return -ENOMEM;
+ cpus_read_lock();
for_each_online_cpu(cpu) {
rc = cpum_cf_alloc_cpu(cpu);
if (rc) {
@@ -302,6 +304,9 @@ static int cpum_cf_alloc(int cpu)
}
cpumask_set_cpu(cpu, mask);
}
+ if (!rc)
+ refcount_inc(&cpu_cf_root.syswide_refcnt);
+ cpus_read_unlock();
free_cpumask_var(mask);
} else {
rc = cpum_cf_alloc_cpu(cpu);
@@ -312,8 +317,11 @@ static int cpum_cf_alloc(int cpu)
static void cpum_cf_free(int cpu)
{
if (cpu == -1) {
+ cpus_read_lock();
+ refcount_dec(&cpu_cf_root.syswide_refcnt);
for_each_online_cpu(cpu)
cpum_cf_free_cpu(cpu);
+ cpus_read_unlock();
} else {
cpum_cf_free_cpu(cpu);
}
@@ -1089,6 +1097,22 @@ static refcount_t cfset_opencnt = REFCOUNT_INIT(0); /* Access count */
*/
static DEFINE_MUTEX(cfset_ctrset_mutex);
+static int cpum_cf_prepare_cpu(unsigned int cpu)
+{
+ int rc = 0;
+
+ if (refcount_read(&cpu_cf_root.syswide_refcnt))
+ rc = cpum_cf_alloc_cpu(cpu);
+ return rc;
+}
+
+static int cpum_cf_dead_cpu(unsigned int cpu)
+{
+ if (refcount_read(&cpu_cf_root.syswide_refcnt))
+ cpum_cf_free_cpu(cpu);
+ return 0;
+}
+
/*
* CPU hotplug handles only /dev/hwctr device.
* For perf_event_open() the CPU hotplug handling is done on kernel common
@@ -1183,7 +1207,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code,
static int cfset_init(void);
static int __init cpumf_pmu_init(void)
{
- int rc;
+ int state, rc;
/* Extract counter measurement facility information */
if (!cpum_cf_avail() || qctri(&cpumf_ctr_info))
@@ -1225,11 +1249,23 @@ static int __init cpumf_pmu_init(void)
cfset_init();
}
+ rc = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN,
+ "perf/s390/cf:prepare",
+ cpum_cf_prepare_cpu, cpum_cf_dead_cpu);
+ if (rc < 0)
+ goto out3;
+ state = rc;
rc = cpuhp_setup_state(CPUHP_AP_PERF_S390_CF_ONLINE,
"perf/s390/cf:online",
cpum_cf_online_cpu, cpum_cf_offline_cpu);
- return rc;
+ if (rc < 0)
+ goto out4;
+ return 0;
+out4:
+ cpuhp_remove_state(state);
+out3:
+ perf_pmu_unregister(&cpumf_pmu);
out2:
debug_unregister_view(cf_dbg, &debug_sprintf_view);
debug_unregister(cf_dbg);
--
2.53.0
next prev parent reply other threads:[~2026-08-09 18:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 13:11 [PATCH] s390/cpum_cf: Handle CPU hotplug add and delete Thomas Richter
2026-08-06 13:29 ` sashiko-bot
2026-08-07 11:46 ` Thomas Richter
2026-08-09 18:18 ` Heiko Carstens
2026-08-09 18:25 ` Heiko Carstens [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-07-31 9:51 Thomas Richter
2026-07-31 10:06 ` sashiko-bot
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=20260809182536.21067B5a-hca@linux.ibm.com \
--to=hca@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=japo@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
--cc=sumanthk@linux.ibm.com \
--cc=tmricht@linux.ibm.com \
/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