Skip to content

Commit 79f2ccc

Browse files
author
Jyri Sarha
committed
module_adapter: generic: Add mod_alloc_lvl2_init() and mod_free_all_lvl2()
Add mod_alloc_lvl2_init() and mod_free_all_lvl2() to enable second level or resource allocations for a module. This second level can be dropped with a single mod_free_all_lvl2() call, but the allocations made before mod_alloc_lvl2_init() call will be kept. The motivation behind this extra layer is Cadence codec module. For the moment it uses mod_alloc() and friends in unorthodox way, and allocates the resources needed at prepare() callback with mod_alloc(), and drops those allocations in reset() callback by calling mod_free_all(). But to do this the module needs to allocate its private data and other with other means than mod_alloc(). The second level of tracked allocations should help with this particular case. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent 1067470 commit 79f2ccc

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

src/audio/module_adapter/module/generic.c

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ static void mod_resource_init(struct processing_module *mod)
7575
{
7676
struct module_data *md = &mod->priv;
7777
/* Init memory list */
78+
md->resources.lvl2_active = false;
7879
list_init(&md->resources.res_list);
80+
list_init(&md->resources.lvl2_res_list);
7981
list_init(&md->resources.free_cont_list);
8082
list_init(&md->resources.cont_chunk_list);
8183
md->resources.heap_usage = 0;
@@ -207,7 +209,10 @@ void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignm
207209
container->ptr = ptr;
208210
container->size = size;
209211
container->type = MOD_RES_HEAP;
210-
list_item_prepend(&container->list, &res->res_list);
212+
if (res->lvl2_active)
213+
list_item_prepend(&container->list, &res->lvl2_res_list);
214+
else
215+
list_item_prepend(&container->list, &res->res_list);
211216

212217
res->heap_usage += size;
213218
if (res->heap_usage > res->heap_high_water_mark)
@@ -258,7 +263,10 @@ void *mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size,
258263
container->ptr = ptr;
259264
container->size = size;
260265
container->type = MOD_RES_HEAP;
261-
list_item_prepend(&container->list, &res->res_list);
266+
if (res->lvl2_active)
267+
list_item_prepend(&container->list, &res->lvl2_res_list);
268+
else
269+
list_item_prepend(&container->list, &res->res_list);
262270

263271
res->heap_usage += size;
264272
if (res->heap_usage > res->heap_high_water_mark)
@@ -298,7 +306,10 @@ mod_data_blob_handler_new(struct processing_module *mod)
298306
container->bhp = bhp;
299307
container->size = 0;
300308
container->type = MOD_RES_BLOB_HANDLER;
301-
list_item_prepend(&container->list, &res->res_list);
309+
if (res->lvl2_active)
310+
list_item_prepend(&container->list, &res->lvl2_res_list);
311+
else
312+
list_item_prepend(&container->list, &res->res_list);
302313

303314
return bhp;
304315
}
@@ -334,7 +345,10 @@ const void *mod_fast_get(struct processing_module *mod, const void * const dram_
334345
container->sram_ptr = ptr;
335346
container->size = 0;
336347
container->type = MOD_RES_FAST_GET;
337-
list_item_prepend(&container->list, &res->res_list);
348+
if (res->lvl2_active)
349+
list_item_prepend(&container->list, &res->lvl2_res_list);
350+
else
351+
list_item_prepend(&container->list, &res->res_list);
338352

339353
return ptr;
340354
}
@@ -375,15 +389,29 @@ int mod_free(struct processing_module *mod, const void *ptr)
375389
{
376390
struct module_resources *res = &mod->priv.resources;
377391
struct module_resource *container;
378-
struct list_item *res_list;
392+
struct list_item *iterator;
379393

380394
MEM_API_CHECK_THREAD(res);
381395
if (!ptr)
382396
return 0;
383397

398+
if (res->lvl2_active) {
399+
/* If level 2 is active, search it first */
400+
list_for_item(iterator, &res->lvl2_res_list) {
401+
container = container_of(iterator, struct module_resource, list);
402+
if (container->ptr == ptr) {
403+
int ret = free_contents(mod, container);
404+
405+
list_item_del(&container->list);
406+
container_put(mod, container);
407+
return ret;
408+
}
409+
}
410+
}
411+
384412
/* Find which container keeps this memory */
385-
list_for_item(res_list, &res->res_list) {
386-
container = container_of(res_list, struct module_resource, list);
413+
list_for_item(iterator, &res->res_list) {
414+
container = container_of(iterator, struct module_resource, list);
387415
if (container->ptr == ptr) {
388416
int ret = free_contents(mod, container);
389417

@@ -415,6 +443,52 @@ void mod_fast_put(struct processing_module *mod, const void *sram_ptr)
415443
EXPORT_SYMBOL(mod_fast_put);
416444
#endif
417445

446+
/**
447+
* Activate second allocation level. All allocations after this call
448+
* are considered 2nd level allocations. The all the 2nd level
449+
* allocations can freed with a single mod_free_all_lvl2() call.
450+
*
451+
* @param mod Pointer to module to start 2nd level allocations.
452+
*/
453+
void mod_alloc_lvl2_init(struct processing_module *mod)
454+
{
455+
struct module_resources *res = &mod->priv.resources;
456+
457+
#if defined(__ZEPHYR__)
458+
__ASSERT(!res->lvl2_active, "Level 2 allocations already activated");
459+
#endif
460+
res->lvl2_active = true;
461+
}
462+
463+
/**
464+
* Free all second level allocations and turn off level 2 allocation.
465+
* Another mod_alloc_lvl2_init() call activates 2nd level again.
466+
*
467+
* @param mod Pointer to module to free 2nd level allocations.
468+
*/
469+
void mod_free_all_lvl2(struct processing_module *mod)
470+
{
471+
struct module_resources *res = &mod->priv.resources;
472+
struct list_item *iterator;
473+
struct list_item *_iterator;
474+
475+
MEM_API_CHECK_THREAD(res);
476+
477+
if (!res->lvl2_active)
478+
return;
479+
480+
/* Free all contents found in lvl2 containers */
481+
list_for_item_safe(iterator, _iterator, &res->lvl2_res_list) {
482+
struct module_resource *container =
483+
container_of(iterator, struct module_resource, list);
484+
485+
free_contents(mod, container);
486+
list_item_del(&container->list);
487+
container_put(mod, container);
488+
}
489+
res->lvl2_active = false;
490+
}
491+
418492
int module_prepare(struct processing_module *mod,
419493
struct sof_source **sources, int num_of_sources,
420494
struct sof_sink **sinks, int num_of_sinks)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ struct module_param {
127127
* when the module unloads.
128128
*/
129129
struct module_resources {
130+
bool lvl2_active;
130131
struct list_item res_list; /**< Allocad resource containers */
132+
struct list_item lvl2_res_list; /**< 2nd level allocated resources */
131133
struct list_item free_cont_list; /**< Unused memory containers */
132134
struct list_item cont_chunk_list; /**< Memory container chunks */
133135
size_t heap_usage;
@@ -235,6 +237,9 @@ const void *mod_fast_get(struct processing_module *mod, const void * const dram_
235237
void mod_fast_put(struct processing_module *mod, const void *sram_ptr);
236238
#endif
237239
void mod_free_all(struct processing_module *mod);
240+
void mod_alloc_lvl2_init(struct processing_module *mod);
241+
void mod_free_all_lvl2(struct processing_module *mod);
242+
238243
int module_prepare(struct processing_module *mod,
239244
struct sof_source **sources, int num_of_sources,
240245
struct sof_sink **sinks, int num_of_sinks);

0 commit comments

Comments
 (0)