-
Notifications
You must be signed in to change notification settings - Fork 364
userspace: proxy: fix multicore work queue handling #11024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
serhiy-katsyuba-intel
wants to merge
3
commits into
thesofproject:main
Choose a base branch
from
serhiy-katsyuba-intel:pin_only_wa
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+183
−44
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| /* SPDX-License-Identifier: BSD-3-Clause | ||
| * | ||
| * Copyright 2026 Intel Corporation. All rights reserved. | ||
| */ | ||
|
|
||
| #ifndef __ZEPHYR_RTOS_USER_WORK_H__ | ||
| #define __ZEPHYR_RTOS_USER_WORK_H__ | ||
|
|
||
| #include <zephyr/kernel.h> | ||
|
|
||
| /** | ||
| * Create a userspace work queue without starting its worker thread. | ||
| * | ||
| * Based on Zephyr's k_work_user_queue_create(), but does not start its | ||
| * worker thread. The caller must configure the thread, for example, pin it | ||
| * to the appropriate core, and call k_thread_start() when it is ready to | ||
| * process work. | ||
| * | ||
| * @param work_q Work queue to initialize. | ||
| * @param stack Worker thread stack. | ||
| * @param stack_size Size of @p stack in bytes. | ||
| * @param prio Worker thread priority. | ||
| * @param name Optional worker thread name. | ||
| */ | ||
| void sof_work_user_queue_create(struct k_work_user_q *work_q, k_thread_stack_t *stack, | ||
| size_t stack_size, int prio, const char *name); | ||
|
|
||
| #endif /* __ZEPHYR_RTOS_USER_WORK_H__ */ |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| /* | ||
| * Copyright (c) 2018 Intel Corporation | ||
| * Copyright (c) 2016 Wind River Systems, Inc. | ||
|
serhiy-katsyuba-intel marked this conversation as resolved.
|
||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| /* | ||
| * This file is mostly copied from Zephyr's user_work.c. Retain the original | ||
| * license header above. | ||
| */ | ||
|
|
||
| /* | ||
| * On Xtensa, with CONFIG_SCHED_CPU_MASK_PIN_ONLY=y, k_thread_cpu_pin() | ||
| * cannot safely change a thread's core after it has been active on another | ||
| * core. Enabling CONFIG_SCHED_CPU_MASK_PIN_ONLY also enables an optimization | ||
| * in the thread-switch code: because Zephyr assumes that a thread will resume | ||
| * on the same core, it does not write back the thread's cached stack. | ||
| * | ||
| * If k_thread_cpu_pin() subsequently moves the thread to another core, the | ||
| * cached stack on the new core contains garbage. The cached stack was not | ||
| * written back on the previous core and is not invalidated on the new core. | ||
| * With CONFIG_SCHED_CPU_MASK_PIN_ONLY disabled, Zephyr writes back the stack | ||
| * when the thread becomes inactive and invalidates it when the thread becomes | ||
| * active on another core. | ||
| * | ||
| * k_work_user_queue_create() starts its worker thread on core 0, leaving no | ||
| * safe way to re-pin it when CONFIG_SCHED_CPU_MASK_PIN_ONLY=y. Because we do | ||
| * not want to disable CONFIG_SCHED_CPU_MASK_PIN_ONLY or use an uncached stack, | ||
| * this file implements a copy of k_work_user_queue_create() that does not | ||
| * start the worker thread. The caller configures the thread, for example by | ||
| * pinning it to the required core, and then calls k_thread_start(). | ||
| */ | ||
|
|
||
| #include <zephyr/kernel.h> | ||
|
|
||
| /* This is an intact copy of Zephyr's z_work_user_q_main(). */ | ||
| static void z_work_user_q_main(void *work_q_ptr, void *p2, void *p3) | ||
| { | ||
| struct k_work_user_q *work_q = work_q_ptr; | ||
|
|
||
| ARG_UNUSED(p2); | ||
| ARG_UNUSED(p3); | ||
|
|
||
| while (true) { | ||
| struct k_work_user *work; | ||
| k_work_user_handler_t handler; | ||
|
|
||
| work = k_queue_get(&work_q->queue, K_FOREVER); | ||
| if (work == NULL) { | ||
| continue; | ||
| } | ||
|
|
||
| handler = work->handler; | ||
| __ASSERT(handler != NULL, "handler must be provided"); | ||
|
|
||
| /* Reset pending state so it can be resubmitted by handler */ | ||
| if (atomic_test_and_clear_bit(&work->flags, | ||
| K_WORK_USER_STATE_PENDING)) { | ||
| handler(work); | ||
| } | ||
|
|
||
| /* Make sure we don't hog up the CPU if the FIFO never (or | ||
| * very rarely) gets empty. | ||
| */ | ||
| k_yield(); | ||
| } | ||
| } | ||
|
|
||
| /* This is Zephyr's k_work_user_queue_create() with k_thread_start() removed. */ | ||
| void sof_work_user_queue_create(struct k_work_user_q *work_q, k_thread_stack_t *stack, | ||
| size_t stack_size, int prio, const char *name) | ||
| { | ||
| k_queue_init(&work_q->queue); | ||
|
|
||
| /* Created worker thread will inherit object permissions and memory | ||
| * domain configuration of the caller | ||
| */ | ||
| k_thread_create(&work_q->thread, stack, stack_size, z_work_user_q_main, | ||
| work_q, NULL, NULL, prio, K_USER | K_INHERIT_PERMS, | ||
| K_FOREVER); | ||
| k_object_access_grant(&work_q->queue, &work_q->thread); | ||
| if (name != NULL) { | ||
| k_thread_name_set(&work_q->thread, name); | ||
| } | ||
| } | ||
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.