Skip to content

[Userspace LL] schedule: zephyr_ll: grant LL thread access to per-task semaphores - #11080

Open
kv2019i wants to merge 1 commit into
thesofproject:mainfrom
kv2019i:202608-userll-sem-grants
Open

[Userspace LL] schedule: zephyr_ll: grant LL thread access to per-task semaphores#11080
kv2019i wants to merge 1 commit into
thesofproject:mainfrom
kv2019i:202608-userll-sem-grants

Conversation

@kv2019i

@kv2019i kv2019i commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

In CONFIG_SOF_USERSPACE_LL builds the LL scheduler thread runs unprivileged, so every Zephyr kernel object it accesses must be explicitly granted to it.

In commit ffa52df ("schedule: ll: dynamically allocate the semaphore"), task semaphores were converted to dynamically allocated objects. Only the bootstrap task's semaphore was granted to the LL thread (in zephyr_ll_init_context()); tasks created later (e.g. chain_dma) were not, so pausing/stopping such a task while it was running crashed the DSP.

Fix the issue by grant the LL scheduling thread access to the task's semaphore at allocation time, from the syscall implementation which runs in privileged context. The task's LL scheduler is resolved via task->sch (bound in schedule_task_init() using the core-explicit user scheduler list), because zephyr_ll_domain()/cpu_get_id()-based helpers are unreliable in a syscall context: zephyr_ll_domain() reads the kernel scheduler list and returns NULL for the user-space LL scheduler.

Add zephyr_domain_thread_tid_for_core() to look up the LL thread for an explicit core without relying on cpu_get_id().

Fixes: ffa52df ("schedule: ll: dynamically allocate the semaphore")

In CONFIG_SOF_USERSPACE_LL builds the LL scheduler thread runs
unprivileged, so every Zephyr kernel object it accesses must be
explicitly granted to it.

In commit ffa52df ("schedule: ll: dynamically allocate the semaphore"),
task semaphores were converted to dynamically allocated objects.
Only the bootstrap task's semaphore was granted to the LL thread (in
zephyr_ll_init_context()); tasks created later (e.g. chain_dma) were
not, so pausing/stopping such a task while it was running crashed the
DSP.

Fix the issue by grant the LL scheduling thread access to the task's
semaphore at allocation time, from the syscall implementation which runs
in privileged context. The task's LL scheduler is resolved via task->sch
(bound in schedule_task_init() using the core-explicit user scheduler
list), because zephyr_ll_domain()/cpu_get_id()-based helpers are
unreliable in a syscall context: zephyr_ll_domain() reads the kernel
scheduler list and returns NULL for the user-space LL scheduler.

Add zephyr_domain_thread_tid_for_core() to look up the LL thread for an
explicit core without relying on cpu_get_id().

Fixes: ffa52df ("schedule: ll: dynamically allocate the semaphore")
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Copilot AI lite review requested due to automatic review settings August 10, 2026 15:37
@kv2019i

kv2019i commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

For context, this is part of #10558

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a userspace permission fault in CONFIG_SOF_USERSPACE_LL builds by ensuring the unprivileged LL scheduler thread is explicitly granted access to per-task semaphores that are dynamically allocated for tasks created after the bootstrap context.

Changes:

  • Grant the LL scheduler thread access to each task’s dynamically allocated semaphore at allocation time (in the privileged syscall implementation path).
  • Add zephyr_domain_thread_tid_for_core() to retrieve the LL thread for a specified core without relying on cpu_get_id() in syscall contexts.
  • Expose the new helper in the LL schedule domain public header.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/schedule/zephyr_ll.c Grants the LL thread access to per-task semaphores during allocation for userspace LL builds.
src/schedule/zephyr_domain.c Adds a core-explicit helper to retrieve the LL scheduler thread TID safely in syscall contexts.
src/include/sof/schedule/ll_schedule_domain.h Declares the new zephyr_domain_thread_tid_for_core() API for userspace LL builds.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/schedule/zephyr_ll.c
Comment on lines +486 to +494
struct zephyr_ll *sch = task->sch ? task->sch->data : NULL;

if (sch && sch->ll_domain) {
struct k_thread *ll_tid =
zephyr_domain_thread_tid_for_core(sch->ll_domain, task->core);

if (ll_tid)
k_thread_access_grant(ll_tid, ts->sem);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants