Skip to content

Commit b1f8daf

Browse files
worker cleanups
Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
1 parent ce0f500 commit b1f8daf

1 file changed

Lines changed: 19 additions & 41 deletions

File tree

src/audio/module_adapter/library/userspace_proxy.c

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,14 @@ static const struct module_interface userspace_proxy_interface;
5656

5757
static inline int user_worker_get(int cpu)
5858
{
59+
ARG_UNUSED(cpu);
5960
return 0;
6061
}
6162

62-
static inline void user_worker_put(int cpu) { }
63+
static inline void user_worker_put(int cpu)
64+
{
65+
ARG_UNUSED(cpu);
66+
}
6367

6468
struct k_work_user *userspace_proxy_register_ipc_handler(struct processing_module *mod,
6569
struct k_event *event)
@@ -86,9 +90,10 @@ struct k_work_user *userspace_proxy_register_ipc_handler(struct processing_modul
8690
* It invokes the appropriate module function in userspace context and writes the operation
8791
* result back into the work item.
8892
*
89-
* There is only a single work queue, which is shared by all userspace modules. It is created
90-
* dynamically when needed. Because SOF uses a single dedicated thread for handling IPC, there
91-
* is no need to perform any additional serialization when accessing the worker.
93+
* There is a separate work queue per core. Each core's work queue is shared by all
94+
* userspace modules running on that core and is created dynamically when needed. A given
95+
* core's worker is only accessed from that same core's IPC handling context, so there is no
96+
* need to perform any additional serialization when accessing it.
9297
*/
9398
struct user_worker {
9499
k_tid_t thread_id; /* ipc worker thread ID */
@@ -100,36 +105,17 @@ struct user_worker {
100105

101106
static struct user_worker worker[CONFIG_CORE_COUNT];
102107

103-
#if 0
104-
static void sof_work_user_queue_init(struct k_work_user_q *work_q, k_thread_stack_t *stack,
105-
size_t stack_size, int prio, const char *name)
106-
{
107-
k_queue_init(&work_q->queue);
108-
109-
/* Created worker thread will inherit object permissions and memory
110-
* domain configuration of the caller
111-
*/
112-
k_thread_create(&work_q->thread, stack, stack_size, z_work_user_q_main,
113-
work_q, NULL, NULL, prio, K_USER | K_INHERIT_PERMS,
114-
K_FOREVER);
115-
k_object_access_grant(&work_q->queue, &work_q->thread);
116-
if (name != NULL) {
117-
k_thread_name_set(&work_q->thread, name);
118-
}
119-
120-
///k_thread_start(&work_q->thread);
121-
}
122-
#endif // 0
123-
124108
static int user_worker_get(int cpu)
125109
{
110+
assert(cpu >= 0 && cpu < (int)ARRAY_SIZE(worker));
111+
126112
if (worker[cpu].reference_count) {
127113
worker[cpu].reference_count++;
128114
return 0;
129115
}
130116

131117
worker[cpu].stack_ptr = user_stack_allocate(CONFIG_SOF_USERSPACE_PROXY_WORKER_STACK_SIZE,
132-
K_USER);
118+
K_USER);
133119
if (!worker[cpu].stack_ptr) {
134120
tr_err(&userspace_proxy_tr, "Userspace worker stack allocation failed.");
135121
return -ENOMEM;
@@ -141,6 +127,10 @@ static int user_worker_get(int cpu)
141127

142128
worker[cpu].thread_id = k_work_user_queue_thread_get(&worker[cpu].work_queue);
143129

130+
/*
131+
* k_work_user_queue_start() starts the worker thread immediately.
132+
* We need to make sure it is not running when pinning it to a specific core.
133+
*/
144134
k_thread_suspend(worker[cpu].thread_id);
145135

146136
/* Pin worker thread to the same core as the module */
@@ -157,6 +147,8 @@ static int user_worker_get(int cpu)
157147

158148
static void user_worker_put(int cpu)
159149
{
150+
assert(cpu >= 0 && cpu < (int)ARRAY_SIZE(worker));
151+
160152
/* Module removed so decrement counter */
161153
worker[cpu].reference_count--;
162154

@@ -178,10 +170,7 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
178170
if (ret)
179171
return ret;
180172

181-
/* We have only a single userspace IPC worker. It handles requests for all userspace
182-
* modules, which may run on different cores. Because the worker processes work items
183-
* coming from any core, the work item must be allocated in coherent memory.
184-
*/
173+
/* TODO: this can probably be allocated as cached? */
185174
work_item = sof_heap_alloc(user_heap, SOF_MEM_FLAG_COHERENT, sizeof(*work_item), 0);
186175
if (!work_item) {
187176
user_worker_put(cpu);
@@ -253,17 +242,6 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
253242
goto done;
254243
}
255244

256-
#if 0
257-
#ifdef CONFIG_SCHED_CPU_MASK
258-
/* Pin worker thread to the same core as the module */
259-
ret = k_thread_cpu_pin(worker[cpu].thread_id, cpu);
260-
if (ret < 0) {
261-
tr_err(&userspace_proxy_tr, "Failed to pin cpu, error: %d", ret);
262-
goto done;
263-
}
264-
#endif
265-
#endif // 0
266-
267245
ret = k_work_user_submit_to_queue(&worker[cpu].work_queue, &user_ctx->work_item->work_item);
268246
if (ret < 0) {
269247
tr_err(&userspace_proxy_tr, "Submit to queue error: %d", ret);

0 commit comments

Comments
 (0)