audio: pipeline: change locking strategy for user LL builds#10957
Open
kv2019i wants to merge 3 commits into
Open
audio: pipeline: change locking strategy for user LL builds#10957kv2019i wants to merge 3 commits into
kv2019i wants to merge 3 commits into
Conversation
Collaborator
Author
|
Keeping as drafts until dependencies are marged and will then update this PR and mark as ready for review. |
09b1d59 to
f1b280d
Compare
Add new functions to lock/unlock the LL scheduler for a given core. This is intended for audio application code that needs to modify the audio pipelines and needs an interface to get exclusive access to the pipelines on a particular core. This interface is specific to SOF builds with CONFIG_SOF_USERSPACE_LL. If LL scheduler is running in kernel space, there is option to disable interrupts for similar effect. For now these code paths are kept separate. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
In user-space LL builds (CONFIG_SOF_USERSPACE_LL), the IPC user thread cannot block interrupts while making modifications to the audio graph. To workaround this limitation, one could either protect each pipeline object with locks, or keep the LL level lock held while executing LL tasks. This patch implements support for the latter approach. If building SOF for user LL, do not release the lock when running a task. This reduces number of syscalls during a LL iteration, and allows to safely implement IPC handlers that need to modify the audio graph. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Modify the locking approach for CONFIG_SOF_USERSPACE_LL builds. Kernel LL implementation heavily relies on ability to disable interrupts when IPC handler is modifying the graph. This ensures a new LL tick and execution of a new graph cycle does not start before the graph modifications done by IPC handler are complete. In user-space, this approach is not available as user-space thread cannot disable interrupts. In commit 1e59ce2 ("pipeline: protect component connections with a mutex"), a sys_mutex based locking was implemented to protect the component list and modifications to it. This approach does not scale in the end as this would require taking the mutex for each component of each pipeline, and take the locks on every LL cycle tick. This results in significant system call overhead. Additionally Zephyr sys_mutex does not work correctly if the lock object is put into dynamically allocated user memory. In this commit, locking the LL graph is moved to a higher level. A single lock is used to protect the whole LL graph, and the lock is taken at start of LL tick. The same lock is taken by the IPC handlers when modifications to the graph are taken. The mutex interface supports priority inversion, so this usage is safe if LL timer tick happens while IPC processing is still in progress. The patch only changes behaviour for userspace LL SOF builds. If LL scheduling is kept in kernel, locking is done as before. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
f1b280d to
1998a42
Compare
Collaborator
Author
|
V2 pushed:
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR changes how mutual exclusion is enforced between the IPC thread and the low-latency (LL) pipeline scheduling path when SOF is built to run LL pipelines in Zephyr user-space, aiming to simplify locking and reduce syscall overhead.
Changes:
- Keep the LL scheduler mutex held while executing LL tasks in user-space LL builds, shifting protection to a single scheduler-level lock.
- Introduce
user_ll_lock_sched()/user_ll_unlock_sched()as a shared locking API for IPC-side operations that must exclude the LL thread. - Remove the per-component list mutex and update IPC/pipeline graph operations to use the LL scheduler lock instead.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/schedule/zephyr_ll.c | Holds the scheduler lock while running LL tasks in user-space builds; adds exported scheduler lock/unlock helpers. |
| src/ipc/ipc4/helper.c | Uses the scheduler lock to protect pipeline/module free and updates LL blocking macros to accept src/dst cores. |
| src/ipc/ipc-helper.c | Uses the scheduler lock (user-space builds) instead of IRQ disable/enable when freeing components and manipulating buffer lists. |
| src/include/sof/schedule/ll_schedule_domain.h | Declares the new user_ll_lock_sched() / user_ll_unlock_sched() APIs. |
| src/include/sof/audio/component.h | Removes the user-space-only per-component list mutex. |
| src/audio/pipeline/pipeline-stream.c | Adds scheduler locking around pipeline_copy() in user-space LL builds. |
| src/audio/pipeline/pipeline-graph.c | Switches connect/disconnect list protection to the scheduler lock (or IRQ disable in kernel builds). |
| * tasks against IPC thread, so the lock must be held | ||
| * while running the tasks. | ||
| * in kernel LL builds, IPC thread blocks interrupts for | ||
| * critical section, so lock can be freed ere. |
| } | ||
|
|
||
| /* Lock buffer lists to prevent racing with the LL scheduler. | ||
| * In user-space builds, use the LL scheduler's sys_mutex |
Comment on lines
+155
to
+156
| #define PPL_LOCK(x) user_ll_lock_sched(x) | ||
| #define PPL_UNLOCK(x) user_ll_unlock_sched(x) |
| */ | ||
| void user_ll_lock_sched(int core) | ||
| { | ||
| assert(core < CONFIG_CORE_COUNT && zephyr_ll_locks[core] != NULL); |
| */ | ||
| void user_ll_unlock_sched(int core) | ||
| { | ||
| assert(core < CONFIG_CORE_COUNT && zephyr_ll_locks[core] != NULL); |
| * tasks against IPC thread, so the lock must be held | ||
| * while running the tasks. | ||
| * in kernel LL builds, IPC thread blocks interrupts for | ||
| * critical section, so lock can be freed ere. |
Comment on lines
+155
to
+156
| #define PPL_LOCK(x) user_ll_lock_sched(x) | ||
| #define PPL_UNLOCK(x) user_ll_unlock_sched(x) |
Comment on lines
+340
to
+343
| /* Lock buffer lists to prevent racing with the LL scheduler. | ||
| * In user-space builds, use the LL scheduler's sys_mutex | ||
| * (re-entrant, so safe if caller already holds it). | ||
| */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A set of patches to change the locking approach for LL audio pipeline scheduling when SOF is built to run all LL pipelines in user-space. The target is to simplify the design and decrease the syscall overhead during typical audio use-cases.
Tested as part of #10558