Skip to content

Commit 6b6af15

Browse files
committed
module: generic: use a single static lock for module resources
Replace the per-pool k_mutex embedded in struct module_resources with a single static K_MUTEX_DEFINE() shared by all module resource pools. This approach to implement locking works both in kernel and userspace SOF builds. When userspace is enabled, the resource API is only ever entered from supervisor context (the z_impl_* syscall bodies), so is it ok to have the lock only accessible from kernel. Lock contention is negligible: resource bookkeeping happens at module setup and teardown, not on the processing path, and the mutex carries priority inheritance for the rare overlap. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent ec22a69 commit 6b6af15

2 files changed

Lines changed: 31 additions & 25 deletions

File tree

src/audio/module_adapter/module/generic.c

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@
2828

2929
LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL);
3030

31+
/*
32+
* A single lock shared by all module resource pools. The resource API is only
33+
* ever entered from supervisor context (the z_impl_* syscall bodies), so the
34+
* lock does not need to live in the per-module, user-writable struct - a static
35+
* kernel object serialises all pools. Contention is negligible because resource
36+
* bookkeeping only happens at module setup/teardown, not on the processing path.
37+
*/
38+
static K_MUTEX_DEFINE(mod_res_lock);
39+
3140
int module_load_config(struct comp_dev *dev, const void *cfg, size_t size)
3241
{
3342
int ret;
@@ -79,7 +88,6 @@ void mod_resource_init(struct processing_module *mod)
7988
struct module_resources *res = &mod->priv.resources;
8089

8190
/* Init memory list */
82-
k_mutex_init(&res->lock);
8391
list_init(&res->objpool.list);
8492
res->objpool.heap = res->alloc->heap;
8593
res->objpool.vreg = res->alloc->vreg;
@@ -179,18 +187,18 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
179187
struct module_resources *res = &mod->priv.resources;
180188
struct module_resource *container;
181189

182-
k_mutex_lock(&res->lock, K_FOREVER);
190+
k_mutex_lock(&mod_res_lock, K_FOREVER);
183191

184192
container = container_get(mod);
185193
if (!container) {
186-
k_mutex_unlock(&res->lock);
194+
k_mutex_unlock(&mod_res_lock);
187195
return NULL;
188196
}
189197

190198
if (!size) {
191199
comp_err(mod->dev, "requested allocation of 0 bytes.");
192200
container_put(mod, container);
193-
k_mutex_unlock(&res->lock);
201+
k_mutex_unlock(&mod_res_lock);
194202
return NULL;
195203
}
196204

@@ -202,7 +210,7 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
202210
comp_err(mod->dev, "Failed to alloc %zu bytes %zu alignment for comp %#x.",
203211
size, alignment, dev_comp_id(mod->dev));
204212
container_put(mod, container);
205-
k_mutex_unlock(&res->lock);
213+
k_mutex_unlock(&mod_res_lock);
206214
return NULL;
207215
}
208216
/* Store reference to allocated memory */
@@ -214,7 +222,7 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
214222
if (res->heap_usage > res->heap_high_water_mark)
215223
res->heap_high_water_mark = res->heap_usage;
216224

217-
k_mutex_unlock(&res->lock);
225+
k_mutex_unlock(&mod_res_lock);
218226
return ptr;
219227
}
220228
EXPORT_SYMBOL(z_impl_mod_balloc_align);
@@ -235,18 +243,18 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t
235243
struct module_resources *res = &mod->priv.resources;
236244
struct module_resource *container;
237245

238-
k_mutex_lock(&res->lock, K_FOREVER);
246+
k_mutex_lock(&mod_res_lock, K_FOREVER);
239247

240248
container = container_get(mod);
241249
if (!container) {
242-
k_mutex_unlock(&res->lock);
250+
k_mutex_unlock(&mod_res_lock);
243251
return NULL;
244252
}
245253

246254
if (!size) {
247255
comp_err(mod->dev, "requested allocation of 0 bytes.");
248256
container_put(mod, container);
249-
k_mutex_unlock(&res->lock);
257+
k_mutex_unlock(&mod_res_lock);
250258
return NULL;
251259
}
252260

@@ -257,7 +265,7 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t
257265
comp_err(mod->dev, "Failed to alloc %zu bytes %zu alignment for comp %#x.",
258266
size, alignment, dev_comp_id(mod->dev));
259267
container_put(mod, container);
260-
k_mutex_unlock(&res->lock);
268+
k_mutex_unlock(&mod_res_lock);
261269
return NULL;
262270
}
263271
/* Store reference to allocated memory */
@@ -269,7 +277,7 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t
269277
if (res->heap_usage > res->heap_high_water_mark)
270278
res->heap_high_water_mark = res->heap_usage;
271279

272-
k_mutex_unlock(&res->lock);
280+
k_mutex_unlock(&mod_res_lock);
273281
return ptr;
274282
}
275283
EXPORT_SYMBOL(z_impl_mod_alloc_ext);
@@ -284,30 +292,29 @@ EXPORT_SYMBOL(z_impl_mod_alloc_ext);
284292
#if CONFIG_COMP_BLOB
285293
struct comp_data_blob_handler *z_impl_mod_data_blob_handler_new(struct processing_module *mod)
286294
{
287-
struct module_resources *res = &mod->priv.resources;
288295
struct comp_data_blob_handler *bhp;
289296
struct module_resource *container;
290297

291-
k_mutex_lock(&res->lock, K_FOREVER);
298+
k_mutex_lock(&mod_res_lock, K_FOREVER);
292299

293300
container = container_get(mod);
294301
if (!container) {
295-
k_mutex_unlock(&res->lock);
302+
k_mutex_unlock(&mod_res_lock);
296303
return NULL;
297304
}
298305

299306
bhp = comp_data_blob_handler_new_ext(mod->dev, false, NULL, NULL);
300307
if (!bhp) {
301308
container_put(mod, container);
302-
k_mutex_unlock(&res->lock);
309+
k_mutex_unlock(&mod_res_lock);
303310
return NULL;
304311
}
305312

306313
container->bhp = bhp;
307314
container->size = 0;
308315
container->type = MOD_RES_BLOB_HANDLER;
309316

310-
k_mutex_unlock(&res->lock);
317+
k_mutex_unlock(&mod_res_lock);
311318
return bhp;
312319
}
313320
EXPORT_SYMBOL(z_impl_mod_data_blob_handler_new);
@@ -328,26 +335,26 @@ const void *z_impl_mod_fast_get(struct processing_module *mod, const void * cons
328335
struct module_resource *container;
329336
const void *ptr;
330337

331-
k_mutex_lock(&res->lock, K_FOREVER);
338+
k_mutex_lock(&mod_res_lock, K_FOREVER);
332339

333340
container = container_get(mod);
334341
if (!container) {
335-
k_mutex_unlock(&res->lock);
342+
k_mutex_unlock(&mod_res_lock);
336343
return NULL;
337344
}
338345

339346
ptr = fast_get(res->alloc, dram_ptr, size);
340347
if (!ptr) {
341348
container_put(mod, container);
342-
k_mutex_unlock(&res->lock);
349+
k_mutex_unlock(&mod_res_lock);
343350
return NULL;
344351
}
345352

346353
container->sram_ptr = ptr;
347354
container->size = 0;
348355
container->type = MOD_RES_FAST_GET;
349356

350-
k_mutex_unlock(&res->lock);
357+
k_mutex_unlock(&mod_res_lock);
351358
return ptr;
352359
}
353360
EXPORT_SYMBOL(z_impl_mod_fast_get);
@@ -425,10 +432,10 @@ int z_impl_mod_free(struct processing_module *mod, const void *ptr)
425432
/* Find which container holds this memory */
426433
struct mod_res_cb_arg cb_arg = {mod, ptr};
427434

428-
k_mutex_lock(&res->lock, K_FOREVER);
435+
k_mutex_lock(&mod_res_lock, K_FOREVER);
429436
int ret = objpool_iterate(&res->objpool, mod_res_free, &cb_arg);
430437

431-
k_mutex_unlock(&res->lock);
438+
k_mutex_unlock(&mod_res_lock);
432439

433440
if (ret < 0)
434441
comp_err(mod->dev, "error: could not find memory pointed by %p", ptr);
@@ -755,10 +762,10 @@ void z_impl_mod_free_all(struct processing_module *mod)
755762
/* Free all contents found in used containers */
756763
struct mod_res_cb_arg cb_arg = {mod, NULL};
757764

758-
k_mutex_lock(&res->lock, K_FOREVER);
765+
k_mutex_lock(&mod_res_lock, K_FOREVER);
759766
objpool_iterate(&res->objpool, mod_res_free, &cb_arg);
760767
objpool_prune(&res->objpool);
761-
k_mutex_unlock(&res->lock);
768+
k_mutex_unlock(&mod_res_lock);
762769

763770
/* Make sure resource lists and accounting are reset */
764771
mod_resource_init(mod);

src/include/sof/audio/module_adapter/module/generic.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ struct module_param {
125125
* when the module unloads.
126126
*/
127127
struct module_resources {
128-
struct k_mutex lock;
129128
struct objpool_head objpool;
130129
size_t heap_usage;
131130
size_t heap_high_water_mark;

0 commit comments

Comments
 (0)