[PATCH] s390/pai: Handle CPU hotplug add for PAI PMU

Thomas Richter <[email protected]>
Newsgroups org.kernel.vger.linux-s390
Message-ID <[email protected]>
The command 'perf stat -e pai_crypto/CRYPTO_ALL/ -- <command>
crashes the kernel when CPUs are hotplug added during that run.

Root cause is the allocation of struct pai_mapptr 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

 # echo 0 > /sys/devices/system/cpu/cpu1/online
 # perf stat -e pai_crypto/CRYPTO_ALL/ -i -- stress-ng -t10s --matrix X
 # sleep 1
 # echo 1 > /sys/devices/system/cpu/cpu1/online

create an event for CPUs 0,2-X. Since the events are created with
task-context, the scheduler will eventually schedule the program
on CPU1. This CPU has not created and initialized any per
CPU event infrastructure as that CPU was not online at the time
of the perf invocation. Thus when the scheduler runs stress-ng
on CPU1, the function pai_add() refers to a NULL pointer:

 struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);

This function call is invoked after the task stress-ng has been
made runnable on CPU1. And variable mp is a NULL pointer.
The result is a panic.

Allocate the necessary per CPU event handling infrastructure for all
possible CPUs, not just the ones currently online.

Fixes: 92ea686840ac ("s390/pai_crypto: Enable per-task counting event")
Cc: <[email protected]> # v6.11+
Signed-off-by: Thomas Richter <[email protected]>
---
 arch/s390/kernel/perf_pai.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c
index cdb8006220ca..793bda20df14 100644
--- a/arch/s390/kernel/perf_pai.c
+++ b/arch/s390/kernel/perf_pai.c
@@ -325,7 +325,7 @@ static int pai_alloc(struct perf_event *event)
 	if (!maskptr)
 		goto out;
 
-	for_each_online_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 		rc = pai_alloc_cpu(event, cpu);
 		if (rc) {
 			for_each_cpu(cpu, maskptr)
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.