Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions posix/include/rtos/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <stdint.h>

#define K_FOREVER ((k_timeout_t) { .ticks = 0xffffffff })
#define K_MUTEX_DEFINE(name) struct k_mutex name

struct k_mutex {
struct k_spinlock lock;
Expand Down
72 changes: 47 additions & 25 deletions src/audio/module_adapter/module/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@

LOG_MODULE_DECLARE(module_adapter, CONFIG_SOF_LOG_LEVEL);

/*
* A single lock shared by all module resource pools. The resource API is only
* ever entered from supervisor context (the z_impl_* syscall bodies), so the
* lock does not need to live in the per-module, user-writable struct - a static
* kernel object serialises all pools. Contention is negligible because resource
* bookkeeping only happens at module setup/teardown, not on the processing path.
*/
static K_MUTEX_DEFINE(mod_res_lock);

int module_load_config(struct comp_dev *dev, const void *cfg, size_t size)
{
int ret;
Expand Down Expand Up @@ -79,7 +88,6 @@ void mod_resource_init(struct processing_module *mod)
struct module_resources *res = &mod->priv.resources;

/* Init memory list */
k_mutex_init(&res->lock);
list_init(&res->objpool.list);
res->objpool.heap = res->alloc->heap;
res->objpool.vreg = res->alloc->vreg;
Expand Down Expand Up @@ -179,18 +187,18 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
struct module_resources *res = &mod->priv.resources;
struct module_resource *container;

k_mutex_lock(&res->lock, K_FOREVER);
k_mutex_lock(&mod_res_lock, K_FOREVER);

container = container_get(mod);
if (!container) {
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

if (!size) {
comp_err(mod->dev, "requested allocation of 0 bytes.");
container_put(mod, container);
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

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

k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return ptr;
}
EXPORT_SYMBOL(z_impl_mod_balloc_align);
Expand All @@ -235,18 +243,18 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t
struct module_resources *res = &mod->priv.resources;
struct module_resource *container;

k_mutex_lock(&res->lock, K_FOREVER);
k_mutex_lock(&mod_res_lock, K_FOREVER);

container = container_get(mod);
if (!container) {
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

if (!size) {
comp_err(mod->dev, "requested allocation of 0 bytes.");
container_put(mod, container);
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

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

k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return ptr;
}
EXPORT_SYMBOL(z_impl_mod_alloc_ext);
Expand All @@ -284,30 +292,29 @@ EXPORT_SYMBOL(z_impl_mod_alloc_ext);
#if CONFIG_COMP_BLOB
struct comp_data_blob_handler *z_impl_mod_data_blob_handler_new(struct processing_module *mod)
{
struct module_resources *res = &mod->priv.resources;
struct comp_data_blob_handler *bhp;
struct module_resource *container;

k_mutex_lock(&res->lock, K_FOREVER);
k_mutex_lock(&mod_res_lock, K_FOREVER);

container = container_get(mod);
if (!container) {
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

bhp = comp_data_blob_handler_new_ext(mod->dev, false, NULL, NULL);
if (!bhp) {
container_put(mod, container);
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

container->bhp = bhp;
container->size = 0;
container->type = MOD_RES_BLOB_HANDLER;

k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return bhp;
}
EXPORT_SYMBOL(z_impl_mod_data_blob_handler_new);
Expand All @@ -328,26 +335,26 @@ const void *z_impl_mod_fast_get(struct processing_module *mod, const void * cons
struct module_resource *container;
const void *ptr;

k_mutex_lock(&res->lock, K_FOREVER);
k_mutex_lock(&mod_res_lock, K_FOREVER);

container = container_get(mod);
if (!container) {
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

ptr = fast_get(res->alloc, dram_ptr, size);
if (!ptr) {
container_put(mod, container);
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return NULL;
}

container->sram_ptr = ptr;
container->size = 0;
container->type = MOD_RES_FAST_GET;

k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);
return ptr;
}
EXPORT_SYMBOL(z_impl_mod_fast_get);
Expand Down Expand Up @@ -425,10 +432,10 @@ int z_impl_mod_free(struct processing_module *mod, const void *ptr)
/* Find which container holds this memory */
struct mod_res_cb_arg cb_arg = {mod, ptr};

k_mutex_lock(&res->lock, K_FOREVER);
k_mutex_lock(&mod_res_lock, K_FOREVER);
int ret = objpool_iterate(&res->objpool, mod_res_free, &cb_arg);

k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);

if (ret < 0)
comp_err(mod->dev, "error: could not find memory pointed by %p", ptr);
Expand Down Expand Up @@ -501,6 +508,20 @@ int z_vrfy_mod_free(struct processing_module *mod, const void *ptr)
}
#include <zephyr/syscalls/mod_free_mrsh.c>

void z_vrfy_mod_free_all(struct processing_module *mod)
{
size_t h_size = 0;
uintptr_t h_start;

K_OOPS(K_SYSCALL_MEMORY_WRITE(mod, sizeof(*mod)));
mod_heap_info(mod, &h_size, &h_start);
if (h_size)
K_OOPS(K_SYSCALL_MEMORY_WRITE(h_start, h_size));

z_impl_mod_free_all(mod);
}
#include <zephyr/syscalls/mod_free_all_mrsh.c>

#if CONFIG_COMP_BLOB
struct comp_data_blob_handler *z_vrfy_mod_data_blob_handler_new(struct processing_module *mod)
{
Expand Down Expand Up @@ -734,21 +755,22 @@ int module_reset(struct processing_module *mod)
*
* This function is called automatically when the module is unloaded.
*/
void mod_free_all(struct processing_module *mod)
void z_impl_mod_free_all(struct processing_module *mod)
{
struct module_resources *res = &mod->priv.resources;

/* Free all contents found in used containers */
struct mod_res_cb_arg cb_arg = {mod, NULL};

k_mutex_lock(&res->lock, K_FOREVER);
k_mutex_lock(&mod_res_lock, K_FOREVER);
objpool_iterate(&res->objpool, mod_res_free, &cb_arg);
objpool_prune(&res->objpool);
k_mutex_unlock(&res->lock);
k_mutex_unlock(&mod_res_lock);

/* Make sure resource lists and accounting are reset */
mod_resource_init(mod);
}
EXPORT_SYMBOL(z_impl_mod_free_all);

int module_free(struct processing_module *mod)
{
Expand Down
5 changes: 3 additions & 2 deletions src/include/sof/audio/module_adapter/module/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ struct module_param {
* when the module unloads.
*/
struct module_resources {
struct k_mutex lock;
struct objpool_head objpool;
size_t heap_usage;
size_t heap_high_water_mark;
Expand Down Expand Up @@ -197,12 +196,15 @@ void mod_heap_info(struct processing_module *mod, size_t *size, uintptr_t *start
__syscall void *mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size,
size_t alignment);
__syscall int mod_free(struct processing_module *mod, const void *ptr);
__syscall void mod_free_all(struct processing_module *mod);
#else
void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size,
size_t alignment);
int z_impl_mod_free(struct processing_module *mod, const void *ptr);
void z_impl_mod_free_all(struct processing_module *mod);
#define mod_alloc_ext z_impl_mod_alloc_ext
#define mod_free z_impl_mod_free
#define mod_free_all z_impl_mod_free_all
#endif

/**
Expand Down Expand Up @@ -259,7 +261,6 @@ const void *z_impl_mod_fast_get(struct processing_module *mod, const void * cons
#endif
void mod_fast_put(struct processing_module *mod, const void *sram_ptr);
#endif
void mod_free_all(struct processing_module *mod);
int module_prepare(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks);
Expand Down
Loading