Skip to content

Commit

Permalink
llext: fix failures with short-lived pipelines
Browse files Browse the repository at this point in the history
When speaker-test stops, it once again creates and immediately
destroys pipelines. This leads to failures with LLEXT. Add a minimum
pipeline life time for such cases.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
  • Loading branch information
lyakh committed Aug 13, 2024
1 parent 5fb99ee commit df0b47d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace15_mtpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ CONFIG_DMA_DW_LLI_POOL_SIZE=50
CONFIG_INTEL_MODULES=y
CONFIG_LIBRARY_MANAGER=y
CONFIG_LIBRARY_AUTH_SUPPORT=y
CONFIG_LIBRARY_PIPELINE_FORCE_MIN_LIFETIME=100
CONFIG_INTEL_ADSP_TIMER=y
CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y
CONFIG_AMS=y
Expand Down
6 changes: 6 additions & 0 deletions src/audio/pipeline/pipeline-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <rtos/interrupt.h>
#include <sof/lib/mm_heap.h>
#include <sof/lib/uuid.h>
#include <sof/llext_manager.h>
#include <sof/compiler_attributes.h>
#include <sof/list.h>
#include <rtos/spinlock.h>
Expand Down Expand Up @@ -260,6 +261,11 @@ static int pipeline_comp_complete(struct comp_dev *current,

/* complete component init */
current->pipeline = ppl_data->p;

if (comp_is_llext(current))
/* pipelines are allocated using rzalloc(), so initially .init_time = 0 */
current->pipeline->init_time = sof_cycle_get_64();

/* LL module has its period always eq period of the pipeline
* DP period is set to 0 as sink format may not yet been set
* It will be calculated during module prepare operation
Expand Down
1 change: 1 addition & 0 deletions src/include/sof/audio/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct pipeline {
bool aborted; /* STOP or PAUSE failed, stay active */
bool pending; /* trigger scheduled but not executed yet */
} trigger;
uint64_t init_time;
};

struct pipeline_walk_context {
Expand Down
12 changes: 12 additions & 0 deletions src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ static int ipc_pipeline_module_free(uint32_t pipeline_id)
int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id)
{
struct ipc_comp_dev *ipc_pipe;
uint64_t life_time;
int ret;

/* check whether pipeline exists */
Expand All @@ -342,6 +343,17 @@ int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id)
if (!cpu_is_me(ipc_pipe->core))
return ipc4_process_on_core(ipc_pipe->core, false);

if (ipc_pipe->pipeline->init_time) {
/*
* This pipeline must not be destroyed before a minimum time
* since its creation has passed
*/
life_time = k_cyc_to_ms_near64(sof_cycle_get_64() - ipc_pipe->pipeline->init_time);
pipe_dbg(ipc_pipe->pipeline, "Extend pipeline life beyond %llu", life_time);
if (life_time < CONFIG_LIBRARY_PIPELINE_FORCE_MIN_LIFETIME)
k_msleep(CONFIG_LIBRARY_PIPELINE_FORCE_MIN_LIFETIME - life_time);
}

ret = ipc_pipeline_module_free(ipc_pipe->pipeline->pipeline_id);
if (ret != IPC4_SUCCESS) {
tr_err(&ipc_tr, "ipc_pipeline_free(): module free () failed");
Expand Down
11 changes: 11 additions & 0 deletions src/library_manager/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,15 @@ config LIBRARY_AUTH_SUPPORT
could be used if enabled.
If unsure say N.

config LIBRARY_PIPELINE_FORCE_MIN_LIFETIME
int "Minimum pipeline life-time in ms"
default 0
range 0 500
help
Typically pipelines are created for streaming, which lasts for
considerable time, at least seconds. But in some test-cases pipelines
are created and quickly destroyed again with no streaming at all. In
some configurations this leads to failures. This option allows setting
a minimum pipeline life-time, which fixes those scenarios.

endmenu

0 comments on commit df0b47d

Please sign in to comment.