diff --git a/src/audio/buffers/comp_buffer.c b/src/audio/buffers/comp_buffer.c index 0c28d9204cd1..4a4c69b469e8 100644 --- a/src/audio/buffers/comp_buffer.c +++ b/src/audio/buffers/comp_buffer.c @@ -559,7 +559,8 @@ static inline struct list_item *buffer_comp_list(struct comp_buffer *buffer, } /* - * Locking: must be called with interrupts disabled! Serialized IPCs protect us + * Locking: must be called with interrupts disabled (or sys_mutex held for + * userspace LL builds)! Serialized IPCs protect us * from racing attach / detach calls, but the scheduler can interrupt the IPC * thread and begin using the buffer for streaming. FIXME: this is still a * problem with different cores. @@ -572,7 +573,8 @@ void buffer_attach(struct comp_buffer *buffer, struct list_item *head, int dir) } /* - * Locking: must be called with interrupts disabled! See buffer_attach() above + * Locking: must be called with interrupts disabled (or sys_mutex held for + * userspace LL builds)! See buffer_attach() above * for details */ void buffer_detach(struct comp_buffer *buffer, struct list_item *head, int dir) diff --git a/src/audio/pipeline/pipeline-graph.c b/src/audio/pipeline/pipeline-graph.c index 89bb3574289b..38053f016bbb 100644 --- a/src/audio/pipeline/pipeline-graph.c +++ b/src/audio/pipeline/pipeline-graph.c @@ -178,24 +178,34 @@ static void buffer_set_comp(struct comp_buffer *buffer, struct comp_dev *comp, comp_buffer_set_sink_component(buffer, comp); } +#ifdef CONFIG_SOF_USERSPACE_LL +#define PPL_LOCK_DECLARE +#define PPL_LOCK() { int ret = sys_mutex_lock(&comp->list_mutex, K_FOREVER); assert(ret == 0); } +#define PPL_UNLOCK() { int ret = sys_mutex_unlock(&comp->list_mutex); assert(ret == 0); } +#else +#define PPL_LOCK_DECLARE uint32_t flags +#define PPL_LOCK() irq_local_disable(flags) +#define PPL_UNLOCK() irq_local_enable(flags) +#endif + int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer, int dir) { struct list_item *comp_list; - uint32_t flags; + PPL_LOCK_DECLARE; if (dir == PPL_CONN_DIR_COMP_TO_BUFFER) comp_info(comp, "connect buffer %d as sink", buf_get_id(buffer)); else comp_info(comp, "connect buffer %d as source", buf_get_id(buffer)); - irq_local_disable(flags); + PPL_LOCK(); comp_list = comp_buffer_list(comp, dir); buffer_attach(buffer, comp_list, dir); buffer_set_comp(buffer, comp, dir); - irq_local_enable(flags); + PPL_UNLOCK(); return 0; } @@ -203,20 +213,20 @@ int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer, void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer, int dir) { struct list_item *comp_list; - uint32_t flags; + PPL_LOCK_DECLARE; if (dir == PPL_CONN_DIR_COMP_TO_BUFFER) comp_dbg(comp, "disconnect buffer %d as sink", buf_get_id(buffer)); else comp_dbg(comp, "disconnect buffer %d as source", buf_get_id(buffer)); - irq_local_disable(flags); + PPL_LOCK(); comp_list = comp_buffer_list(comp, dir); buffer_detach(buffer, comp_list, dir); buffer_set_comp(buffer, NULL, dir); - irq_local_enable(flags); + PPL_UNLOCK(); } /* pipelines must be inactive */ diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index b6695b9cd312..82b9599df8c8 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -679,6 +680,10 @@ struct comp_dev { struct list_item bsource_list; /**< list of source buffers */ struct list_item bsink_list; /**< list of sink buffers */ +#ifdef CONFIG_SOF_USERSPACE_LL + struct sys_mutex list_mutex; /**< protect lists of source/sinks */ +#endif + /* performance data*/ struct comp_perf_data perf_data; /* Input Buffer Size for pin 0, add array for other pins if needed */ @@ -863,6 +868,9 @@ static inline void comp_init(const struct comp_driver *drv, dev->state = COMP_STATE_INIT; list_init(&dev->bsink_list); list_init(&dev->bsource_list); +#ifdef CONFIG_SOF_USERSPACE_LL + sys_mutex_init(&dev->list_mutex); +#endif memcpy_s(&dev->tctx, sizeof(dev->tctx), trace_comp_drv_get_tr_ctx(dev->drv), sizeof(struct tr_ctx)); }