1 From 117b4dfc411cc5896e800a18ff9469c9f9db7da2 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Thu, 27 Apr 2023 10:33:31 +0200
4 Subject: s390/pai_ext: replace atomic_t with refcount_t
6 From: Thomas Richter <tmricht@linux.ibm.com>
8 [ Upstream commit 1f2597cd3686955a4d64e01909dbfe625a2a35a1 ]
10 The s390 PMU of PAI extension 1 NNPA counters uses atomic_t for
11 reference counting. Replace this with the proper data type
16 Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
17 Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
18 Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
19 Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
20 Signed-off-by: Sasha Levin <sashal@kernel.org>
22 arch/s390/kernel/perf_pai_ext.c | 23 +++++++++++++----------
23 1 file changed, 13 insertions(+), 10 deletions(-)
25 diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
26 index b4d89654183a2..d6bc919530143 100644
27 --- a/arch/s390/kernel/perf_pai_ext.c
28 +++ b/arch/s390/kernel/perf_pai_ext.c
29 @@ -56,7 +56,7 @@ struct paiext_map {
30 struct pai_userdata *save; /* Area to store non-zero counters */
31 enum paiext_mode mode; /* Type of event */
32 unsigned int active_events; /* # of PAI Extension users */
33 - unsigned int refcnt;
35 struct perf_event *event; /* Perf event for sampling */
36 struct paiext_cb *paiext_cb; /* PAI extension control block area */
38 @@ -66,14 +66,14 @@ struct paiext_mapptr {
41 static struct paiext_root { /* Anchor to per CPU data */
42 - int refcnt; /* Overall active events */
43 + refcount_t refcnt; /* Overall active events */
44 struct paiext_mapptr __percpu *mapptr;
47 /* Free per CPU data when the last event is removed. */
48 static void paiext_root_free(void)
50 - if (!--paiext_root.refcnt) {
51 + if (refcount_dec_and_test(&paiext_root.refcnt)) {
52 free_percpu(paiext_root.mapptr);
53 paiext_root.mapptr = NULL;
55 @@ -86,7 +86,7 @@ static void paiext_root_free(void)
57 static int paiext_root_alloc(void)
59 - if (++paiext_root.refcnt == 1) {
60 + if (!refcount_inc_not_zero(&paiext_root.refcnt)) {
61 /* The memory is already zeroed. */
62 paiext_root.mapptr = alloc_percpu(struct paiext_mapptr);
63 if (!paiext_root.mapptr) {
64 @@ -97,6 +97,7 @@ static int paiext_root_alloc(void)
68 + refcount_set(&paiext_root.refcnt, 1);
72 @@ -128,7 +129,7 @@ static void paiext_event_destroy(struct perf_event *event)
74 mutex_lock(&paiext_reserve_mutex);
76 - if (!--cpump->refcnt) /* Last reference gone */
77 + if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
80 mutex_unlock(&paiext_reserve_mutex);
81 @@ -169,7 +170,7 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
83 cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
88 /* Allocate memory for counter area and counter extraction.
90 @@ -189,8 +190,9 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
92 if (!cpump->save || !cpump->area || !cpump->paiext_cb) {
97 + refcount_set(&cpump->refcnt, 1);
98 cpump->mode = a->sample_period ? PAI_MODE_SAMPLING
101 @@ -201,15 +203,15 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
102 if (cpump->mode == PAI_MODE_SAMPLING ||
103 (cpump->mode == PAI_MODE_COUNTER && a->sample_period)) {
108 + refcount_inc(&cpump->refcnt);
112 cpump->event = event;
118 /* Error in allocation of event, decrement anchor. Since
119 * the event in not created, its destroy() function is never
120 @@ -217,6 +219,7 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
125 mutex_unlock(&paiext_reserve_mutex);
126 /* If rc is non-zero, no increment of counter/sampler was done. */