Skip to content
Open
26 changes: 23 additions & 3 deletions app/boards/intel_adsp_ace30_ptl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n
CONFIG_PROBE=y
CONFIG_PROBE_DMA_MAX=2
CONFIG_SOF_TELEMETRY=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=y
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_COLD_STORE_EXECUTE_DRAM=y

# SOF / loadable modules
Expand Down Expand Up @@ -82,4 +82,24 @@ CONFIG_SOF_STACK_SIZE=8192
CONFIG_SOF_USERSPACE_PROXY=y
CONFIG_MAX_THREAD_BYTES=3

CONFIG_MAX_DOMAIN_PARTITIONS=32
CONFIG_MAX_DOMAIN_PARTITIONS=64

# Userspace LL (was app/overlays/ptl/ll_userspace_overlay.conf)
# Run Low-Latency audio pipelines in user-space threads by default.
CONFIG_SOF_USERSPACE_LL=y
CONFIG_SOF_USERSPACE_INTERFACE_DMA=y
CONFIG_DAI_USERSPACE=y

# Settings currently required to enable user-space LL. The cold-store,
# telemetry, loadable-module and misc feature disables above/here are not
# yet user-space compatible (see the former overlay for rationale).
CONFIG_COLD_STORE_EXECUTE_DEBUG=n
CONFIG_SOF_BOOT_TEST_ALLOWED=n
CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
# Extend the shared LL user-space heap to 0.5MB. This
# is current maximum for PTL builds with virtual heap
# enabled and uses the vmh allocation intended for KBP.
# TODO: needs some better solution to allocate
CONFIG_SOF_ZEPHYR_SYS_USER_HEAP_SIZE=0x80000
37 changes: 35 additions & 2 deletions app/boards/intel_adsp_ace30_wcl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n
CONFIG_PROBE=y
CONFIG_PROBE_DMA_MAX=2
CONFIG_SOF_TELEMETRY=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=y
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_COLD_STORE_EXECUTE_DRAM=y

# SOF / loadable modules
Expand Down Expand Up @@ -69,3 +69,36 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n
CONFIG_LOG_BACKEND_ADSP=n
CONFIG_LOG_FLUSH_SLEEP_US=5000
CONFIG_WINSTREAM_CONSOLE=n

# Userspace base (mirrored from intel_adsp_ace30_ptl.conf)
# Required so that user-space LL (below) can actually be enabled, since
# CONFIG_SOF_USERSPACE_LL depends on CONFIG_USERSPACE.
CONFIG_USERSPACE=y
CONFIG_DYNAMIC_THREAD=y
CONFIG_DYNAMIC_THREAD_ALLOC=y
CONFIG_DYNAMIC_THREAD_PREFER_ALLOC=y
CONFIG_SOF_STACK_SIZE=8192
CONFIG_SOF_USERSPACE_PROXY=y
CONFIG_MAX_THREAD_BYTES=3
CONFIG_MAX_DOMAIN_PARTITIONS=64
CONFIG_XTENSA_MMU_NUM_L2_TABLES=128

# Userspace LL (was app/overlays/ptl/ll_userspace_overlay.conf)
# Run Low-Latency audio pipelines in user-space threads by default.
CONFIG_SOF_USERSPACE_LL=y
CONFIG_SOF_USERSPACE_INTERFACE_DMA=y
CONFIG_DAI_USERSPACE=y

# Settings currently required to enable user-space LL. The cold-store,
# telemetry, loadable-module and misc feature disables above/here are not
# yet user-space compatible (see the former overlay for rationale).
CONFIG_COLD_STORE_EXECUTE_DEBUG=n
CONFIG_SOF_BOOT_TEST_ALLOWED=n
CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
# Extend the shared LL user-space heap to 0.5MB. This
# is current maximum for WCL builds with virtual heap
# enabled and uses the vmh allocation intended for KBP.
# TODO: needs some better solution to allocate
CONFIG_SOF_ZEPHYR_SYS_USER_HEAP_SIZE=0x80000
3 changes: 3 additions & 0 deletions app/overlays/ptl/ll_userspace_overlay.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
# enabled and uses the vmh allocation intended for KBP.
# TODO: needs some better solution to allocate
CONFIG_SOF_ZEPHYR_SYS_USER_HEAP_SIZE=0x80000

# sof-ptl-nocodec.tplg requires more than 32 partitions for DP
CONFIG_MAX_DOMAIN_PARTITIONS=64
155 changes: 82 additions & 73 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *
static
struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
const struct comp_ipc_config *config,
const struct module_ext_init_data *ext_init)
const struct module_ext_init_data *ext_init,
struct mod_alloc_ctx *ppl_alloc)
{
struct k_heap *mod_heap;
struct vregion *mod_vreg;
struct k_heap *mod_heap = NULL;
struct processing_module *mod;
struct mod_alloc_ctx *alloc;
struct comp_dev *dev;
/*
* For DP shared modules the struct processing_module object must be
Expand All @@ -92,49 +93,53 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
*/
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
bool use_ppl_alloc = ppl_alloc &&
config->proc_domain == COMP_PROCESSING_DOMAIN_LL;

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, ext_init);
if (!mod_vreg) {
comp_cl_err(drv, "Failed to allocate DP module heap / vregion");
return NULL;
}
if (use_ppl_alloc) {
/* LL modules share the pipeline's alloc context */
alloc = ppl_alloc;
vregion_get(alloc->vreg);
} else {
struct vregion *mod_vreg = NULL;

if (IS_ENABLED(CONFIG_SOF_VREGIONS) && IS_ENABLED(CONFIG_USERSPACE) &&
!IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP) &&
config->proc_domain == COMP_PROCESSING_DOMAIN_DP) {
mod_vreg = module_adapter_dp_heap_new(config, ext_init);
if (!mod_vreg) {
comp_cl_err(drv, "Failed to allocate DP module heap / vregion");
return NULL;
}
#ifdef CONFIG_SOF_USERSPACE_LL
mod_heap = sof_sys_user_heap_get();
#else
mod_heap = NULL;
mod_heap = sof_sys_user_heap_get();
#endif
} else {
} else {
#ifdef CONFIG_SOF_USERSPACE_LL
mod_heap = sof_sys_user_heap_get();
comp_cl_dbg(drv, "using ll user heap for module");
mod_heap = sof_sys_user_heap_get();
comp_cl_dbg(drv, "using ll user heap for module");
#else
mod_heap = drv->user_heap;
mod_heap = drv->user_heap;
#endif
mod_vreg = NULL;
}
}
alloc = sof_heap_alloc(mod_heap, flags, sizeof(*alloc), 0);
if (!alloc) {
vregion_put(mod_vreg);
return NULL;
}

if (!mod_vreg)
mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0);
else if (flags & SOF_MEM_FLAG_COHERENT)
mod = vregion_alloc_coherent(mod_vreg, sizeof(*mod));
else
mod = vregion_alloc(mod_vreg, sizeof(*mod));
memset(alloc, 0, sizeof(*alloc));
alloc->heap = mod_heap;
alloc->vreg = mod_vreg;
}

mod = sof_ctx_alloc(alloc, flags, sizeof(*mod), 0);
if (!mod) {
comp_cl_err(drv, "failed to allocate memory for module");
goto emod;
}

struct mod_alloc_ctx *alloc = sof_heap_alloc(mod_heap, flags, sizeof(*alloc), 0);

if (!alloc)
goto ealloc;

memset(mod, 0, sizeof(*mod));
alloc->heap = mod_heap;
alloc->vreg = mod_vreg;
mod->priv.resources.alloc = alloc;
mod_resource_init(mod);

Expand All @@ -144,11 +149,7 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
* then it can be cached. Effectively it can be only cached in
* single-core configurations.
*/
if (mod_vreg)
dev = vregion_alloc_coherent(mod_vreg, sizeof(*dev));
else
dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);

dev = sof_ctx_alloc(alloc, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
if (!dev) {
comp_cl_err(drv, "failed to allocate memory for comp_dev");
goto edev;
Expand All @@ -163,41 +164,39 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
return mod;

edev:
sof_heap_free(mod_heap, alloc);
ealloc:
if (mod_vreg)
vregion_free(mod_vreg, mod);
else
sof_heap_free(mod_heap, mod);
sof_ctx_free(alloc, mod);
emod:
vregion_put(mod_vreg);
vregion_put(alloc->vreg);
if (!use_ppl_alloc)
sof_heap_free(mod_heap, alloc);

return NULL;
}

static void module_adapter_mem_free(struct processing_module *mod)
{
struct mod_alloc_ctx *alloc = mod->priv.resources.alloc;
struct k_heap *mod_heap = alloc->heap;
bool ppl_alloc = mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL &&
mod->dev->pipeline && mod->dev->pipeline->alloc == alloc;

/*
* In principle it shouldn't even be needed to free individual objects
* on the module heap since we're freeing the heap itself too
*/
#if CONFIG_IPC_MAJOR_4
sof_heap_free(mod_heap, mod->priv.cfg.input_pins);
sof_heap_free(alloc->heap, mod->priv.cfg.input_pins);
#endif
if (alloc->vreg) {
struct vregion *mod_vreg = alloc->vreg;

vregion_free(mod_vreg, mod->dev);
vregion_free(mod_vreg, mod);
if (!vregion_put(mod_vreg))
sof_heap_free(alloc->heap, alloc);
sof_ctx_free(alloc, mod->dev);
sof_ctx_free(alloc, mod);

if (ppl_alloc) {
/* alloc belongs to pipeline, just release vregion reference */
vregion_put(alloc->vreg);
} else if (alloc->vreg) {
if (!vregion_put(alloc->vreg))
rfree(alloc);
} else {
sof_heap_free(mod_heap, mod->dev);
sof_heap_free(mod_heap, mod);
sof_heap_free(mod_heap, alloc);
rfree(alloc);
}
}

Expand Down Expand Up @@ -248,8 +247,19 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
NULL;
#endif

struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init);
struct mod_alloc_ctx *ppl_alloc = NULL;
#if CONFIG_IPC_MAJOR_4
struct ipc_comp_dev *ipc_pipe;
struct ipc *ipc = ipc_get();

/* resolve the pipeline pointer early to pass its alloc to mem_alloc */
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
IPC_COMP_IGNORE_REMOTE);
if (ipc_pipe && ipc_pipe->pipeline)
ppl_alloc = ipc_pipe->pipeline->alloc;
#endif

struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init, ppl_alloc);
if (!mod)
return NULL;

Expand All @@ -273,6 +283,21 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
dst->ext_data = &ext_data;
#endif

#if CONFIG_IPC_MAJOR_4
/*
* Set the pipeline pointer if ipc_pipe is valid. Do this
* early so that we can use module_adapter_mem_free() in error
* handling.
*/
if (ipc_pipe) {
dev->pipeline = ipc_pipe->pipeline;

/* LL modules have the same period as the pipeline */
if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL)
dev->period = ipc_pipe->pipeline->period;
}
#endif

#if CONFIG_ZEPHYR_DP_SCHEDULER
/* create a task for DP processing */
if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) {
Expand Down Expand Up @@ -306,22 +331,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
else
goto err;

#if CONFIG_IPC_MAJOR_4
struct ipc_comp_dev *ipc_pipe;
struct ipc *ipc = ipc_get();

/* set the pipeline pointer if ipc_pipe is valid */
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
IPC_COMP_IGNORE_REMOTE);
if (ipc_pipe) {
dev->pipeline = ipc_pipe->pipeline;

/* LL modules have the same period as the pipeline */
if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL)
dev->period = ipc_pipe->pipeline->period;
}
#endif

/* Init processing module */
ret = module_init(mod);
if (ret) {
Expand Down
Loading
Loading