ptl: userspace: handle userspace module IPC in the DP thread#10952
Open
serhiy-katsyuba-intel wants to merge 1 commit into
Open
ptl: userspace: handle userspace module IPC in the DP thread#10952serhiy-katsyuba-intel wants to merge 1 commit into
serhiy-katsyuba-intel wants to merge 1 commit into
Conversation
The current k_work_user_q-based worker used for userspace IPC processing does not work in the multicore case. An assert is triggered in k_thread_cpu_pin() when a userspace module is created on a secondary core. k_thread_cpu_pin() only works for a thread that is not currently running. Unfortunately, k_work_user_queue_start() not only initializes the queue but also immediately starts its worker thread on core 0. By the time k_thread_cpu_pin() is called, the worker thread may still be running (in our test it always is) and has not yet reached the wait condition in its loop where it goes to sleep. Wrapping the k_thread_cpu_pin() call in k_thread_suspend() and k_thread_resume() does not help either: this time the firmware hangs (sometimes, depending on the log level) in k_thread_suspend() due to a race. If the worker thread reaches its wait condition just before the IPI (triggered by k_thread_suspend()) is processed, k_thread_suspend() waits forever for the thread to become suspended. A possible fix would be to create a work queue per core and pin their threads from core 0, e.g. from secondary_core_init(). Or, more simply, switch to the implementation that uses the DP thread, as is done here. Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR enables processing of userspace module IPC via the DP thread on Panther Lake (ACE30 PTL), avoiding the existing k_work_user_q-based worker approach that breaks in multicore scenarios.
Changes:
- Enable
CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREADfor theintel_adsp_ace30_ptlboard configuration.
| CONFIG_DYNAMIC_THREAD_ALLOC=y | ||
| CONFIG_DYNAMIC_THREAD_PREFER_ALLOC=y | ||
| CONFIG_SOF_STACK_SIZE=8192 | ||
| CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD=y |
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.
The current k_work_user_q-based worker used for userspace IPC processing does not work in the multicore case. An assert is triggered in k_thread_cpu_pin() when a userspace module is created on a secondary core.
k_thread_cpu_pin() only works for a thread that is not currently running. Unfortunately, k_work_user_queue_start() not only initializes the queue but also immediately starts its worker thread on core 0. By the time k_thread_cpu_pin() is called, the worker thread may still be running (in our test it always is) and has not yet reached the wait condition in its loop where it goes to sleep.
Wrapping the k_thread_cpu_pin() call in k_thread_suspend() and k_thread_resume() does not help either: this time the firmware hangs (sometimes, depending on the log level) in k_thread_suspend() due to a race. If the worker thread reaches its wait condition just before the IPI (triggered by k_thread_suspend()) is processed, k_thread_suspend() waits forever for the thread to become suspended.
A possible fix would be to create a work queue per core and pin their threads from core 0, e.g. from secondary_core_init(). Or, more simply, switch to the implementation that uses the DP thread, as is done here.