summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/perf_pai_ext.c
diff options
context:
space:
mode:
authorThomas Richter <tmricht@linux.ibm.com>2024-02-29 17:00:28 +0300
committerVasily Gorbik <gor@linux.ibm.com>2024-04-03 16:00:20 +0300
commite9f3af02f63909f41b43c28330434cc437639c5c (patch)
treee5b5b84cfbabd3865fa6b4b8b64bf2476795352b /arch/s390/kernel/perf_pai_ext.c
parentc9c260681f521e4ad9f9f4cc71fe35b978e06222 (diff)
downloadlinux-e9f3af02f63909f41b43c28330434cc437639c5c.tar.xz
s390/pai: fix sampling event removal for PMU device driver
In case of a sampling event, the PAI PMU device drivers need a reference to this event. Currently to PMU device driver reference is removed when a sampling event is destroyed. This may lead to situations where the reference of the PMU device driver is removed while being used by a different sampling event. Reset the event reference pointer of the PMU device driver when a sampling event is deleted and before the next one might be added. Fixes: 39d62336f5c1 ("s390/pai: add support for cryptography counters") Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/perf_pai_ext.c')
-rw-r--r--arch/s390/kernel/perf_pai_ext.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
index 616a25606cd6..a6da7e0cc7a6 100644
--- a/arch/s390/kernel/perf_pai_ext.c
+++ b/arch/s390/kernel/perf_pai_ext.c
@@ -122,7 +122,6 @@ static void paiext_event_destroy(struct perf_event *event)
free_page(PAI_SAVE_AREA(event));
mutex_lock(&paiext_reserve_mutex);
- cpump->event = NULL;
if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
paiext_free(mp);
paiext_root_free();
@@ -362,10 +361,15 @@ static int paiext_add(struct perf_event *event, int flags)
static void paiext_stop(struct perf_event *event, int flags)
{
- if (!event->attr.sample_period) /* Counting */
+ struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
+ struct paiext_map *cpump = mp->mapptr;
+
+ if (!event->attr.sample_period) { /* Counting */
paiext_read(event);
- else /* Sampling */
+ } else { /* Sampling */
perf_sched_cb_dec(event->pmu);
+ cpump->event = NULL;
+ }
event->hw.state = PERF_HES_STOPPED;
}