]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.1/s390-pai_ext-replace-atomic_t-with-refcount_t.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / queue-6.1 / s390-pai_ext-replace-atomic_t-with-refcount_t.patch
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
5
6 From: Thomas Richter <tmricht@linux.ibm.com>
7
8 [ Upstream commit 1f2597cd3686955a4d64e01909dbfe625a2a35a1 ]
9
10 The s390 PMU of PAI extension 1 NNPA counters uses atomic_t for
11 reference counting. Replace this with the proper data type
12 refcount_t.
13
14 No functional change.
15
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>
21 ---
22 arch/s390/kernel/perf_pai_ext.c | 23 +++++++++++++----------
23 1 file changed, 13 insertions(+), 10 deletions(-)
24
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;
34 + refcount_t refcnt;
35 struct perf_event *event; /* Perf event for sampling */
36 struct paiext_cb *paiext_cb; /* PAI extension control block area */
37 };
38 @@ -66,14 +66,14 @@ struct paiext_mapptr {
39 };
40
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;
45 } paiext_root;
46
47 /* Free per CPU data when the last event is removed. */
48 static void paiext_root_free(void)
49 {
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;
54 }
55 @@ -86,7 +86,7 @@ static void paiext_root_free(void)
56 */
57 static int paiext_root_alloc(void)
58 {
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)
65 */
66 return -ENOMEM;
67 }
68 + refcount_set(&paiext_root.refcnt, 1);
69 }
70 return 0;
71 }
72 @@ -128,7 +129,7 @@ static void paiext_event_destroy(struct perf_event *event)
73
74 mutex_lock(&paiext_reserve_mutex);
75 cpump->event = NULL;
76 - if (!--cpump->refcnt) /* Last reference gone */
77 + if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
78 paiext_free(mp);
79 paiext_root_free();
80 mutex_unlock(&paiext_reserve_mutex);
81 @@ -169,7 +170,7 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
82 rc = -ENOMEM;
83 cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
84 if (!cpump)
85 - goto unlock;
86 + goto undo;
87
88 /* Allocate memory for counter area and counter extraction.
89 * These are
90 @@ -189,8 +190,9 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
91 GFP_KERNEL);
92 if (!cpump->save || !cpump->area || !cpump->paiext_cb) {
93 paiext_free(mp);
94 - goto unlock;
95 + goto undo;
96 }
97 + refcount_set(&cpump->refcnt, 1);
98 cpump->mode = a->sample_period ? PAI_MODE_SAMPLING
99 : PAI_MODE_COUNTER;
100 } else {
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)) {
104 rc = -EBUSY;
105 - goto unlock;
106 + goto undo;
107 }
108 + refcount_inc(&cpump->refcnt);
109 }
110
111 rc = 0;
112 cpump->event = event;
113 - ++cpump->refcnt;
114
115 -unlock:
116 +undo:
117 if (rc) {
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)
121 */
122 paiext_root_free();
123 }
124 +unlock:
125 mutex_unlock(&paiext_reserve_mutex);
126 /* If rc is non-zero, no increment of counter/sampler was done. */
127 return rc;
128 --
129 2.43.0
130