Skip to content

Commit fed1761

Browse files
committed
audio: pipeline: use LL scheduler mutex for userspace pipeline triggers
In CONFIG_SOF_USERSPACE_LL builds, irq_local_disable() is not available. Replace the no-op irq guard with the LL scheduler's own k_mutex to prevent the scheduler from processing tasks while pipeline state is being updated. The k_mutex is re-entrant so schedule_task() calls inside the critical section are safe. Add zephyr_ll_lock_sched() and zephyr_ll_unlock_sched() helpers that acquire and release the scheduler mutex, and call them from pipeline_schedule_triggered() under CONFIG_SOF_USERSPACE_LL. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent 1c7576f commit fed1761

3 files changed

Lines changed: 42 additions & 1 deletion

File tree

src/audio/pipeline/pipeline-schedule.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <sof/lib/agent.h>
1414
#include <sof/list.h>
1515
#include <sof/schedule/ll_schedule.h>
16+
#include <sof/schedule/ll_schedule_domain.h>
1617
#include <sof/schedule/dp_schedule.h>
1718
#include <sof/schedule/schedule.h>
1819
#include <sof/audio/module_adapter/module/generic.h>
@@ -282,6 +283,16 @@ void pipeline_schedule_triggered(struct pipeline_walk_context *ctx,
282283
struct pipeline_data *ppl_data = ctx->comp_data;
283284
struct list_item *tlist;
284285
struct pipeline *p;
286+
287+
#ifdef CONFIG_SOF_USERSPACE_LL
288+
/*
289+
* In user-space irq_local_disable() is not available. Use the LL
290+
* scheduler mutex to prevent the scheduler from processing tasks
291+
* while pipeline state is being updated. The k_mutex is re-entrant
292+
* so schedule_task() calls inside the critical section are safe.
293+
*/
294+
zephyr_ll_lock_sched();
295+
#else
285296
uint32_t flags;
286297

287298
/*
@@ -290,6 +301,7 @@ void pipeline_schedule_triggered(struct pipeline_walk_context *ctx,
290301
* immediately before all pipelines achieved a consistent state.
291302
*/
292303
irq_local_disable(flags);
304+
#endif
293305

294306
switch (cmd) {
295307
case COMP_TRIGGER_PAUSE:
@@ -345,8 +357,11 @@ void pipeline_schedule_triggered(struct pipeline_walk_context *ctx,
345357
p->xrun_bytes = 1;
346358
}
347359
}
348-
360+
#ifdef CONFIG_SOF_USERSPACE_LL
361+
zephyr_ll_unlock_sched();
362+
#else
349363
irq_local_enable(flags);
364+
#endif
350365
}
351366

352367
int pipeline_comp_ll_task_init(struct pipeline *p)

src/include/sof/schedule/ll_schedule_domain.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ void zephyr_ll_task_free(struct task *task);
117117
struct k_heap *zephyr_ll_user_heap(void);
118118
void zephyr_ll_user_resources_init(void);
119119
void zephyr_ll_grant_access(struct k_thread *thread);
120+
void zephyr_ll_lock_sched(void);
121+
void zephyr_ll_unlock_sched(void);
120122
#endif /* CONFIG_SOF_USERSPACE_LL */
121123

122124
static inline struct ll_schedule_domain *domain_init

src/schedule/zephyr_ll.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,30 @@ void zephyr_ll_grant_access(struct k_thread *thread)
578578
k_thread_access_grant(thread, ll_sch->lock);
579579
}
580580

581+
/**
582+
* Lock the LL scheduler to prevent it from processing tasks.
583+
*
584+
* Uses the LL scheduler's own k_mutex which is re-entrant, so
585+
* schedule_task() calls within the locked section will not deadlock.
586+
* Must be paired with zephyr_ll_unlock_sched().
587+
*/
588+
void zephyr_ll_lock_sched(void)
589+
{
590+
struct zephyr_ll *sch = (struct zephyr_ll *)scheduler_get_data(SOF_SCHEDULE_LL_TIMER);
591+
592+
k_mutex_lock(sch->lock, K_FOREVER);
593+
}
594+
595+
/**
596+
* Unlock the LL scheduler after a previous zephyr_ll_lock_sched() call.
597+
*/
598+
void zephyr_ll_unlock_sched(void)
599+
{
600+
struct zephyr_ll *sch = (struct zephyr_ll *)scheduler_get_data(SOF_SCHEDULE_LL_TIMER);
601+
602+
k_mutex_unlock(sch->lock);
603+
}
604+
581605
#endif /* CONFIG_SOF_USERSPACE_LL */
582606

583607
int zephyr_ll_task_init(struct task *task,

0 commit comments

Comments
 (0)