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: 1 addition & 1 deletion src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +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);
sof_heap_free(alloc->heap, alloc);
} else {
sof_heap_free(alloc ? alloc->heap : NULL, buffer);
}
Expand Down
22 changes: 9 additions & 13 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,6 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
return module_adapter_new_ext(drv, config, spec, NULL, NULL, NULL);
}

static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config,
size_t *heap_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;

return vregion_create(buf_size);
}

static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
const struct comp_ipc_config *config)
{
Expand All @@ -77,11 +67,15 @@ 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);
/* src-lite with 8 channels has been seen allocating 14k in one go */
/* FIXME: the size will be derived from configuration */
vreg_size = 28 * 1024;
mod_vreg = vregion_create_map(&vreg_start, &vreg_size);
if (!mod_vreg) {
comp_cl_err(drv, "Failed to allocate DP module heap / vregion");
return NULL;
Expand All @@ -98,7 +92,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 Down Expand Up @@ -199,6 +194,7 @@ static void module_adapter_mem_free(struct processing_module *mod)
*
* Note: Use the ext version if you need to set the module's private data before calling
* the create method.
* Note 2: ATM runs in privileged / kernel mode for DP modules
*/
struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
const struct comp_ipc_config *config,
Expand Down
56 changes: 40 additions & 16 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 thread
lyakh marked this conversation as resolved.
#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -40,6 +42,13 @@ enum vregion_mem_type {
*/
struct vregion *vregion_create(size_t memsize);

/**
* @brief Create and map a new virtual region instance.
*
* Like above, but usable by userspace and can add domain access.
*/
__syscall struct vregion *vregion_create_map(uintptr_t *vreg_start, size_t *vreg_size);

/**
* @brief Switch virtual region allocations to interim mode.
*
Expand All @@ -49,7 +58,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 +69,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,39 +80,45 @@ 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.
* @brief Allocate aligned memory from the specified virtual region.
*
* Allocate aligned memory from the specified virtual region using the
* current allocation mode (lifetime or interim).
*
* @param[in] vr Pointer to the virtual region instance.
* @param[in] size Size of memory to allocate in bytes.
* @param[in] alignment Alignment 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_align(struct vregion *vr, size_t size, size_t alignment);

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

/**
* @brief Allocate aligned memory from the specified virtual region.
*
* Allocate aligned memory from the specified virtual region using the
* current allocation mode (lifetime or interim).
* @brief Allocate memory from the specified virtual region.
*
* @param[in] vr Pointer to the virtual region instance.
* @param[in] size Size of memory to allocate in bytes.
* @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);
static inline void *vregion_alloc(struct vregion *vr, size_t size)
{
return vregion_alloc_align(vr, size, 0);
}

/**
* @brief like vregion_alloc_align() but allocates coherent memory
* @brief like vregion_alloc() but allocates coherent memory
*/
void *vregion_alloc_coherent_align(struct vregion *vr, size_t size, size_t alignment);
static inline void *vregion_alloc_coherent(struct vregion *vr, size_t size)
{
return vregion_alloc_coherent_align(vr, size, 0);
}

/**
* @brief Free memory allocated from the specified virtual region.
Expand All @@ -113,7 +128,7 @@ 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);

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

bool vregion_verify(struct vregion *vr);

#include <zephyr/syscalls/vregion.h>

#else /* CONFIG_SOF_VREGIONS */

struct vregion {
Expand All @@ -141,6 +160,10 @@ static inline struct vregion *vregion_create(size_t memsize)
{
return NULL;
}
static inline struct vregion *vregion_create_map(uintptr_t *vreg_start, size_t *vreg_size)
{
return NULL;
}
static inline void vregion_set_interim(struct vregion *vr) {}
static inline struct vregion *vregion_get(struct vregion *vr)
{
Expand Down Expand Up @@ -174,6 +197,7 @@ static inline void vregion_mem_info(struct vregion *vr, size_t *size, uintptr_t
if (size)
*size = 0;
}
static inline bool vregion_verify(struct vregion *vr) {return false;}

#endif /* CONFIG_SOF_VREGIONS */

Expand Down
3 changes: 2 additions & 1 deletion src/schedule/zephyr_dp_schedule_application.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ static void scheduler_dp_thread_name_set(k_tid_t thread_id, struct processing_mo
#define scheduler_dp_thread_name_set(x, y)
#endif

/* Called only in IPC context */
/* Called only in IPC context in kernel mode (this can change) */
int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid,
const struct task_ops *ops, struct processing_module *mod,
uint16_t core, size_t stack_size, uint32_t options)
Expand All @@ -437,6 +437,7 @@ int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid,

/* must be called on the same core the task will be bound to */
assert(cpu_get_id() == core);
assert(!k_is_user_context());

/*
* allocate memory
Expand Down
2 changes: 2 additions & 0 deletions zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/schedule/ll_schedule_domain.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/ipc4/handler.h)
zephyr_syscall_header(include/rtos/alloc.h)
zephyr_library_sources_ifdef(CONFIG_SOF_USERSPACE_INTERFACE_ALLOC syscall/alloc.c)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/lib/vregion.h)
zephyr_library_sources_ifdef(CONFIG_SOF_USERSPACE_INTERFACE_VREGION syscall/vregion.c)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/lib/dai-zephyr.h)
zephyr_library_sources_ifdef(CONFIG_USERSPACE syscall/dai.c)

Expand Down
9 changes: 9 additions & 0 deletions zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,20 @@ config SOF_USERSPACE_INTERFACE_ALLOC
Allow user-space threads to use sof_heap_alloc/sof_heap_free
as Zephyr system calls.

config SOF_USERSPACE_INTERFACE_VREGION
bool "Enable SOF vregion interface to userspace threads"
depends on USERSPACE
depends on SOF_VREGIONS
help
Allow user-space threads to use vregion_alloc/vregion_free
and their variants as Zephyr system calls.

config SOF_USERSPACE_LL
bool "Run Low-Latency pipelines in userspace threads"
depends on USERSPACE
select SOF_USERSPACE_INTERFACE_ALLOC
select SOF_USERSPACE_INTERFACE_DMA
select SOF_USERSPACE_INTERFACE_VREGION if SOF_VREGIONS
help
Run Low-Latency (LL) pipelines in userspace threads. This adds
memory protection between operating system resources and
Expand Down
6 changes: 2 additions & 4 deletions zephyr/lib/userspace_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ int user_access_to_mailbox(struct k_mem_domain *domain, k_tid_t thread_id)
if (ret < 0)
return ret;

#if defined(CONFIG_SOF_USERSPACE_LL) && defined(CONFIG_IPC_MAJOR_4)
#ifdef CONFIG_IPC_MAJOR_4
/* HOSTBOX partitions for IPC4 module init parameter block reads.
* comp_new_ipc4() accesses MAILBOX_HOSTBOX_BASE directly to get
* the module configuration data sent by the host.
Expand Down Expand Up @@ -141,9 +141,7 @@ int user_access_to_mailbox(struct k_mem_domain *domain, k_tid_t thread_id)
ret = k_mem_domain_add_partition(domain, &hostbox_partition);
if (ret < 0)
return ret;
#endif /* CONFIG_IPC_MAJOR_4 */

#ifndef CONFIG_IPC_MAJOR_4
#else /* CONFIG_IPC_MAJOR_4 */
/*
* Next mailbox_stream (not available in IPC4). Stream access is cached,
* so different mapping this time.
Expand Down
Loading
Loading