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
2 changes: 2 additions & 0 deletions posix/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ struct vregion;
struct mod_alloc_ctx {
struct k_heap *heap;
struct vregion *vreg;
uintptr_t vreg_start;
size_t vreg_size;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <sof/audio/sink_api.h>
#include <sof/audio/source_api.h>
#include <sof/audio/sink_source_utils.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <rtos/userspace_helper.h>
#include <sof/common.h>
#include <rtos/interrupt.h>
Expand Down Expand Up @@ -165,8 +166,7 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer)

if (alloc && alloc->vreg) {
vregion_free(alloc->vreg, buffer);
if (!vregion_put(alloc->vreg))
rfree(alloc);
module_adapter_vreg_free(alloc);
} else {
sof_heap_free(alloc ? alloc->heap : NULL, buffer);
}
Expand Down
104 changes: 96 additions & 8 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,80 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
#define PAGE_SZ HOST_PAGE_SIZE
#endif

static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config,
size_t *heap_size)
struct vregion *z_impl_module_adapter_vreg_new(const struct comp_ipc_config *config,
uintptr_t *vreg_start, size_t *vreg_size)
{
/* src-lite with 8 channels has been seen allocating 14k in one go */
/* FIXME: the size will be derived from configuration */
const size_t buf_size = 28 * 1024;
struct vregion *vr = vregion_create(buf_size);

return vregion_create(buf_size);
if (!vr)
return NULL;

#ifdef CONFIG_SOF_USERSPACE_LL
vregion_mem_info(vr, vreg_size, vreg_start);

/*
* In the userspace LL case allocations are also performed by the
* userspace IPC thread, which is also the one, executing this syscall
*/
struct k_mem_partition part = {
.start = *vreg_start,
.size = *vreg_size,
.attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB,
};
int ret = k_mem_domain_add_partition(zephyr_ll_mem_domain(), &part);

if (ret < 0) {
vregion_put(vr);
return NULL;
}

part.start = (uintptr_t)sys_cache_uncached_ptr_get((void *)part.start);
part.attr = K_MEM_PARTITION_P_RW_U_RW;

ret = k_mem_domain_add_partition(zephyr_ll_mem_domain(), &part);
if (ret < 0) {
vregion_put(vr);
return NULL;
}
#else
(void)vreg_start;
(void)vreg_size;
#endif

return vr;
}

void z_impl_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc)
{
#ifdef CONFIG_SOF_USERSPACE_LL
struct k_mem_partition part = {
.start = alloc->vreg_start,
.size = alloc->vreg_size,
.attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB,
};

k_mem_domain_remove_partition(zephyr_ll_mem_domain(), &part);

part.start = (uintptr_t)sys_cache_uncached_ptr_get((void *)part.start);
part.attr = K_MEM_PARTITION_P_RW_U_RW;

k_mem_domain_remove_partition(zephyr_ll_mem_domain(), &part);
#else
(void)alloc;
#endif
}

void module_adapter_vreg_free(struct mod_alloc_ctx *alloc)
{
if (vregion_put(alloc->vreg))
return;

module_adapter_vreg_unmap(alloc);

sof_heap_free(alloc->heap, alloc);
}

static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
Expand All @@ -84,11 +150,12 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
*/
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
size_t heap_size;
size_t vreg_size;
uintptr_t vreg_start;

if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_SOF_VREGIONS) &&
IS_ENABLED(CONFIG_USERSPACE) && !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) {
mod_vreg = module_adapter_dp_heap_new(config, &heap_size);
mod_vreg = module_adapter_vreg_new(config, &vreg_start, &vreg_size);
if (!mod_vreg) {
comp_cl_err(drv, "Failed to allocate DP module heap / vregion");
return NULL;
Expand All @@ -105,7 +172,8 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
#else
mod_heap = drv->user_heap;
#endif
heap_size = 0;
vreg_size = 0;
vreg_start = 0;
mod_vreg = NULL;
}

Expand All @@ -129,6 +197,8 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
memset(mod, 0, sizeof(*mod));
alloc->heap = mod_heap;
alloc->vreg = mod_vreg;
alloc->vreg_start = vreg_start;
alloc->vreg_size = vreg_size;
mod->priv.resources.alloc = alloc;
mod_resource_init(mod);

Expand Down Expand Up @@ -169,6 +239,25 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
return NULL;
}

#ifdef CONFIG_USERSPACE
#include <zephyr/internal/syscall_handler.h>
struct vregion *z_vrfy_module_adapter_vreg_new(const struct comp_ipc_config *config,
uintptr_t *vreg_start, size_t *vreg_size)
{
K_OOPS(K_SYSCALL_MEMORY_WRITE(vreg_start, sizeof(*vreg_start)));
K_OOPS(K_SYSCALL_MEMORY_WRITE(vreg_size, sizeof(*vreg_size)));
K_OOPS(K_SYSCALL_MEMORY_READ(config, sizeof(*config)));
return z_impl_module_adapter_vreg_new(config, vreg_start, vreg_size);
}
#include <zephyr/syscalls/module_adapter_vreg_new_mrsh.c>
void z_vrfy_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc)
{
K_OOPS(K_SYSCALL_MEMORY_READ(alloc, sizeof(*alloc)));
z_impl_module_adapter_vreg_unmap(alloc);
}
#include <zephyr/syscalls/module_adapter_vreg_unmap_mrsh.c>
#endif

static void module_adapter_mem_free(struct processing_module *mod)
{
struct mod_alloc_ctx *alloc = mod->priv.resources.alloc;
Expand All @@ -186,8 +275,7 @@ static void module_adapter_mem_free(struct processing_module *mod)

vregion_free(mod_vreg, mod->dev);
vregion_free(mod_vreg, mod);
if (!vregion_put(mod_vreg))
sof_heap_free(alloc->heap, alloc);
module_adapter_vreg_free(alloc);
} else {
sof_heap_free(mod_heap, mod->dev);
sof_heap_free(mod_heap, mod);
Expand Down
9 changes: 9 additions & 0 deletions src/include/sof/audio/module_adapter/module/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,25 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
#endif
void mod_resource_init(struct processing_module *mod);
void mod_heap_info(struct processing_module *mod, size_t *size, uintptr_t *start);
void module_adapter_vreg_free(struct mod_alloc_ctx *alloc);
#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
__syscall struct vregion *module_adapter_vreg_new(const struct comp_ipc_config *config,
uintptr_t *vreg_start, size_t *vreg_size);
__syscall void module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc);
Comment on lines +197 to +199
__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
struct vregion *z_impl_module_adapter_vreg_new(const struct comp_ipc_config *config,
uintptr_t *vreg_start, size_t *vreg_size);
void z_impl_module_adapter_vreg_unmap(const struct mod_alloc_ctx *alloc);
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 module_adapter_vreg_new z_impl_module_adapter_vreg_new
#define module_adapter_vreg_unmap z_impl_module_adapter_vreg_unmap
#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
Expand Down
30 changes: 22 additions & 8 deletions src/include/sof/lib/vregion.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#define __SOF_LIB_VREGION_H__

#include <stddef.h>
#include <stdint.h>
#include <sof/compiler_attributes.h>

Comment on lines 8 to 11
#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -49,7 +51,7 @@ struct vregion *vregion_create(size_t memsize);
*
* @param[in] vr Pointer to the virtual region instance.
*/
void vregion_set_interim(struct vregion *vr);
__syscall void vregion_set_interim(struct vregion *vr);

/**
* @brief Increment virtual region's user count.
Expand All @@ -60,7 +62,7 @@ void vregion_set_interim(struct vregion *vr);
* @param[in] vr Pointer to the virtual region instance to release.
* @return struct vregion* Pointer to the virtual region instance.
*/
struct vregion *vregion_get(struct vregion *vr);
__syscall struct vregion *vregion_get(struct vregion *vr);

/**
* @brief Decrement virtual region's user count or destroy it.
Expand All @@ -71,7 +73,7 @@ struct vregion *vregion_get(struct vregion *vr);
* @param[in] vr Pointer to the virtual region instance to release.
* @return struct vregion* Pointer to the virtual region instance or NULL if it has been destroyed.
*/
struct vregion *vregion_put(struct vregion *vr);
__syscall struct vregion *vregion_put(struct vregion *vr);

/**
* @brief Allocate memory from the specified virtual region.
Expand All @@ -80,12 +82,16 @@ struct vregion *vregion_put(struct vregion *vr);
* @param[in] size Size of memory to allocate in bytes.
* @return void* Pointer to the allocated memory, or NULL on failure.
*/
void *vregion_alloc(struct vregion *vr, size_t size);
__syscall void *vregion_alloc(struct vregion *vr, size_t size);

void *z_impl_vregion_alloc(struct vregion *vr, size_t size);

/**
* @brief like vregion_alloc() but allocates coherent memory
*/
void *vregion_alloc_coherent(struct vregion *vr, size_t size);
__syscall void *vregion_alloc_coherent(struct vregion *vr, size_t size);

void *z_impl_vregion_alloc_coherent(struct vregion *vr, size_t size);

/**
* @brief Allocate aligned memory from the specified virtual region.
Expand All @@ -98,12 +104,16 @@ void *vregion_alloc_coherent(struct vregion *vr, size_t size);
* @param[in] alignment Alignment of memory to allocate in bytes.
* @return void* Pointer to the allocated memory, or NULL on failure.
*/
void *vregion_alloc_align(struct vregion *vr, size_t size, size_t alignment);
__syscall void *vregion_alloc_align(struct vregion *vr, size_t size, size_t alignment);

void *z_impl_vregion_alloc_align(struct vregion *vr, size_t size, size_t alignment);

/**
* @brief like vregion_alloc_align() but allocates coherent memory
*/
void *vregion_alloc_coherent_align(struct vregion *vr, size_t size, size_t alignment);
__syscall void *vregion_alloc_coherent_align(struct vregion *vr, size_t size, size_t alignment);

void *z_impl_vregion_alloc_coherent_align(struct vregion *vr, size_t size, size_t alignment);

/**
* @brief Free memory allocated from the specified virtual region.
Expand All @@ -113,7 +123,9 @@ void *vregion_alloc_coherent_align(struct vregion *vr, size_t size, size_t align
* @param[in] vr Pointer to the virtual region instance.
* @param[in] ptr Pointer to the memory to free.
*/
void vregion_free(struct vregion *vr, void *ptr);
__syscall void vregion_free(struct vregion *vr, void *ptr);

void z_impl_vregion_free(struct vregion *vr, void *ptr);

/**
* @brief Log virtual region memory usage.
Expand All @@ -131,6 +143,8 @@ void vregion_info(struct vregion *vr);
*/
void vregion_mem_info(struct vregion *vr, size_t *size, uintptr_t *start);

#include <zephyr/syscalls/vregion.h>

#else /* CONFIG_SOF_VREGIONS */

struct vregion {
Expand Down
20 changes: 20 additions & 0 deletions test/cmocka/src/audio/buffer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ cmocka_test(buffer_copy
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c
${PROJECT_SOURCE_DIR}/src/audio/component.c
${PROJECT_SOURCE_DIR}/src/audio/data_blob.c
${PROJECT_SOURCE_DIR}/src/math/numbers.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c
)

cmocka_test(buffer_new
Expand All @@ -45,7 +50,12 @@ cmocka_test(buffer_new
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c
${PROJECT_SOURCE_DIR}/src/audio/component.c
${PROJECT_SOURCE_DIR}/src/audio/data_blob.c
${PROJECT_SOURCE_DIR}/src/math/numbers.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c
)

cmocka_test(buffer_wrap
Expand All @@ -69,7 +79,12 @@ cmocka_test(buffer_wrap
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c
${PROJECT_SOURCE_DIR}/src/audio/component.c
${PROJECT_SOURCE_DIR}/src/audio/data_blob.c
${PROJECT_SOURCE_DIR}/src/math/numbers.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c
)

cmocka_test(buffer_write
Expand All @@ -93,5 +108,10 @@ cmocka_test(buffer_write
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c
${PROJECT_SOURCE_DIR}/src/audio/component.c
${PROJECT_SOURCE_DIR}/src/audio/data_blob.c
${PROJECT_SOURCE_DIR}/src/math/numbers.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c
)
4 changes: 4 additions & 0 deletions test/cmocka/src/audio/component/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ cmocka_test(comp_set_state
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c
${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c
${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c
)
4 changes: 4 additions & 0 deletions test/cmocka/src/audio/pcm_converter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ if(CONFIG_FORMAT_FLOAT)
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c
${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c
)
target_include_directories(pcm_float_generic PRIVATE ${PROJECT_SOURCE_DIR}/src/include)
target_compile_definitions(pcm_float_generic PRIVATE PCM_CONVERTER_GENERIC)
Expand Down
Loading
Loading