Skip to content

Commit 8c45fa2

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 fc847de commit 8c45fa2

2 files changed

Lines changed: 31 additions & 24 deletions

File tree

src/audio/module_adapter/module/generic.c

Lines changed: 31 additions & 23 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);
@@ -288,26 +296,26 @@ struct comp_data_blob_handler *z_impl_mod_data_blob_handler_new(struct processin
288296
struct comp_data_blob_handler *bhp;
289297
struct module_resource *container;
290298

291-
k_mutex_lock(&res->lock, K_FOREVER);
299+
k_mutex_lock(&mod_res_lock, K_FOREVER);
292300

293301
container = container_get(mod);
294302
if (!container) {
295-
k_mutex_unlock(&res->lock);
303+
k_mutex_unlock(&mod_res_lock);
296304
return NULL;
297305
}
298306

299307
bhp = comp_data_blob_handler_new_ext(mod->dev, false, NULL, NULL);
300308
if (!bhp) {
301309
container_put(mod, container);
302-
k_mutex_unlock(&res->lock);
310+
k_mutex_unlock(&mod_res_lock);
303311
return NULL;
304312
}
305313

306314
container->bhp = bhp;
307315
container->size = 0;
308316
container->type = MOD_RES_BLOB_HANDLER;
309317

310-
k_mutex_unlock(&res->lock);
318+
k_mutex_unlock(&mod_res_lock);
311319
return bhp;
312320
}
313321
EXPORT_SYMBOL(z_impl_mod_data_blob_handler_new);
@@ -328,26 +336,26 @@ const void *z_impl_mod_fast_get(struct processing_module *mod, const void * cons
328336
struct module_resource *container;
329337
const void *ptr;
330338

331-
k_mutex_lock(&res->lock, K_FOREVER);
339+
k_mutex_lock(&mod_res_lock, K_FOREVER);
332340

333341
container = container_get(mod);
334342
if (!container) {
335-
k_mutex_unlock(&res->lock);
343+
k_mutex_unlock(&mod_res_lock);
336344
return NULL;
337345
}
338346

339347
ptr = fast_get(res->alloc, dram_ptr, size);
340348
if (!ptr) {
341349
container_put(mod, container);
342-
k_mutex_unlock(&res->lock);
350+
k_mutex_unlock(&mod_res_lock);
343351
return NULL;
344352
}
345353

346354
container->sram_ptr = ptr;
347355
container->size = 0;
348356
container->type = MOD_RES_FAST_GET;
349357

350-
k_mutex_unlock(&res->lock);
358+
k_mutex_unlock(&mod_res_lock);
351359
return ptr;
352360
}
353361
EXPORT_SYMBOL(z_impl_mod_fast_get);
@@ -425,10 +433,10 @@ int z_impl_mod_free(struct processing_module *mod, const void *ptr)
425433
/* Find which container holds this memory */
426434
struct mod_res_cb_arg cb_arg = {mod, ptr};
427435

428-
k_mutex_lock(&res->lock, K_FOREVER);
436+
k_mutex_lock(&mod_res_lock, K_FOREVER);
429437
int ret = objpool_iterate(&res->objpool, mod_res_free, &cb_arg);
430438

431-
k_mutex_unlock(&res->lock);
439+
k_mutex_unlock(&mod_res_lock);
432440

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

758-
k_mutex_lock(&res->lock, K_FOREVER);
766+
k_mutex_lock(&mod_res_lock, K_FOREVER);
759767
objpool_iterate(&res->objpool, mod_res_free, &cb_arg);
760768
objpool_prune(&res->objpool);
761-
k_mutex_unlock(&res->lock);
769+
k_mutex_unlock(&mod_res_lock);
762770

763771
/* Make sure resource lists and accounting are reset */
764772
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)