Skip to content

Commit 09dc397

Browse files
Thomas Richterhcahca
authored andcommitted
s390/pai_crypto: Consolidate PAI crypto allocation and cleanup paths
Introduce paicrypt_free() to centralize memory release for per-CPU maps and remove duplicated free logic. Replace paicrypt_busy() with paicrypt_alloc_cpu() returning int error codes instead of ERR_PTR, and adjust callers accordingly. System-wide allocation now uses paicrypt_alloc() with consistent error handling. Memory allocation and free management is now identical to PMU pai_ext. Reference counting and root anchor management remain unchanged. Debug output in the destroy path is dropped. Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> Tested-by: Jan Polensky <japo@linux.ibm.com> Reviewed-by: Jan Polensky <japo@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 9daa5a8 commit 09dc397

File tree

1 file changed

+44
-62
lines changed

1 file changed

+44
-62
lines changed

arch/s390/kernel/perf_pai_crypto.c

Lines changed: 44 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ static int paicrypt_root_alloc(void)
8080
/* Release the PMU if event is the last perf event */
8181
static DEFINE_MUTEX(pai_reserve_mutex);
8282

83+
/* Free all memory allocated for event counting/sampling setup */
84+
static void paicrypt_free(struct paicrypt_mapptr *mp)
85+
{
86+
free_page((unsigned long)mp->mapptr->page);
87+
kvfree(mp->mapptr->save);
88+
kfree(mp->mapptr);
89+
mp->mapptr = NULL;
90+
}
91+
8392
/* Adjust usage counters and remove allocated memory when all users are
8493
* gone.
8594
*/
@@ -93,15 +102,8 @@ static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu)
93102
"refcnt %u\n", __func__, event->attr.config,
94103
event->cpu, cpump->active_events,
95104
refcount_read(&cpump->refcnt));
96-
if (refcount_dec_and_test(&cpump->refcnt)) {
97-
debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n",
98-
__func__, (unsigned long)cpump->page,
99-
cpump->save);
100-
free_page((unsigned long)cpump->page);
101-
kvfree(cpump->save);
102-
kfree(cpump);
103-
mp->mapptr = NULL;
104-
}
105+
if (refcount_dec_and_test(&cpump->refcnt))
106+
paicrypt_free(mp);
105107
paicrypt_root_free();
106108
mutex_unlock(&pai_reserve_mutex);
107109
}
@@ -175,14 +177,13 @@ static u64 paicrypt_getall(struct perf_event *event)
175177
*
176178
* Allocate the memory for the event.
177179
*/
178-
static struct paicrypt_map *paicrypt_busy(struct perf_event *event, int cpu)
180+
static int paicrypt_alloc_cpu(struct perf_event *event, int cpu)
179181
{
180182
struct paicrypt_map *cpump = NULL;
181183
struct paicrypt_mapptr *mp;
182184
int rc;
183185

184186
mutex_lock(&pai_reserve_mutex);
185-
186187
/* Allocate root node */
187188
rc = paicrypt_root_alloc();
188189
if (rc)
@@ -192,58 +193,44 @@ static struct paicrypt_map *paicrypt_busy(struct perf_event *event, int cpu)
192193
mp = per_cpu_ptr(paicrypt_root.mapptr, cpu);
193194
cpump = mp->mapptr;
194195
if (!cpump) { /* Paicrypt_map allocated? */
196+
rc = -ENOMEM;
195197
cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
196-
if (!cpump) {
197-
rc = -ENOMEM;
198-
goto free_root;
198+
if (!cpump)
199+
goto undo;
200+
/* Allocate memory for counter page and counter extraction.
201+
* Only the first counting event has to allocate a page.
202+
*/
203+
mp->mapptr = cpump;
204+
cpump->page = (unsigned long *)get_zeroed_page(GFP_KERNEL);
205+
cpump->save = kvmalloc_array(paicrypt_cnt + 1,
206+
sizeof(struct pai_userdata),
207+
GFP_KERNEL);
208+
if (!cpump->page || !cpump->save) {
209+
paicrypt_free(mp);
210+
goto undo;
199211
}
200212
INIT_LIST_HEAD(&cpump->syswide_list);
201-
}
202-
203-
/* Allocate memory for counter page and counter extraction.
204-
* Only the first counting event has to allocate a page.
205-
*/
206-
if (cpump->page) {
213+
refcount_set(&cpump->refcnt, 1);
214+
rc = 0;
215+
} else {
207216
refcount_inc(&cpump->refcnt);
208-
goto unlock;
209217
}
210218

211-
rc = -ENOMEM;
212-
cpump->page = (unsigned long *)get_zeroed_page(GFP_KERNEL);
213-
if (!cpump->page)
214-
goto free_paicrypt_map;
215-
cpump->save = kvmalloc_array(paicrypt_cnt + 1,
216-
sizeof(struct pai_userdata), GFP_KERNEL);
217-
if (!cpump->save) {
218-
free_page((unsigned long)cpump->page);
219-
cpump->page = NULL;
220-
goto free_paicrypt_map;
219+
undo:
220+
if (rc) {
221+
/* Error in allocation of event, decrement anchor. Since
222+
* the event in not created, its destroy() function is never
223+
* invoked. Adjust the reference counter for the anchor.
224+
*/
225+
paicrypt_root_free();
221226
}
222-
223-
/* Set mode and reference count */
224-
rc = 0;
225-
refcount_set(&cpump->refcnt, 1);
226-
mp->mapptr = cpump;
227-
debug_sprintf_event(cfm_dbg, 5, "%s users %d refcnt %u page %#lx "
228-
"save %p rc %d\n", __func__, cpump->active_events,
229-
refcount_read(&cpump->refcnt),
230-
(unsigned long)cpump->page, cpump->save, rc);
231-
goto unlock;
232-
233-
free_paicrypt_map:
234-
/* Undo memory allocation */
235-
kfree(cpump);
236-
mp->mapptr = NULL;
237-
free_root:
238-
paicrypt_root_free();
239227
unlock:
240228
mutex_unlock(&pai_reserve_mutex);
241-
return rc ? ERR_PTR(rc) : cpump;
229+
return rc;
242230
}
243231

244-
static int paicrypt_event_init_all(struct perf_event *event)
232+
static int paicrypt_alloc(struct perf_event *event)
245233
{
246-
struct paicrypt_map *cpump;
247234
struct cpumask *maskptr;
248235
int cpu, rc = -ENOMEM;
249236

@@ -252,12 +239,11 @@ static int paicrypt_event_init_all(struct perf_event *event)
252239
goto out;
253240

254241
for_each_online_cpu(cpu) {
255-
cpump = paicrypt_busy(event, cpu);
256-
if (IS_ERR(cpump)) {
242+
rc = paicrypt_alloc_cpu(event, cpu);
243+
if (rc) {
257244
for_each_cpu(cpu, maskptr)
258245
paicrypt_event_destroy_cpu(event, cpu);
259246
kfree(maskptr);
260-
rc = PTR_ERR(cpump);
261247
goto out;
262248
}
263249
cpumask_set_cpu(cpu, maskptr);
@@ -279,7 +265,6 @@ static int paicrypt_event_init_all(struct perf_event *event)
279265
static int paicrypt_event_init(struct perf_event *event)
280266
{
281267
struct perf_event_attr *a = &event->attr;
282-
struct paicrypt_map *cpump;
283268
int rc = 0;
284269

285270
/* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */
@@ -301,13 +286,10 @@ static int paicrypt_event_init(struct perf_event *event)
301286
}
302287
}
303288

304-
if (event->cpu >= 0) {
305-
cpump = paicrypt_busy(event, event->cpu);
306-
if (IS_ERR(cpump))
307-
rc = PTR_ERR(cpump);
308-
} else {
309-
rc = paicrypt_event_init_all(event);
310-
}
289+
if (event->cpu >= 0)
290+
rc = paicrypt_alloc_cpu(event, event->cpu);
291+
else
292+
rc = paicrypt_alloc(event);
311293
if (rc) {
312294
free_page(PAI_SAVE_AREA(event));
313295
goto out;

0 commit comments

Comments
 (0)