Skip to content

Commit 29d5026

Browse files
committed
wip
1 parent c56fd07 commit 29d5026

5 files changed

Lines changed: 111 additions & 25 deletions

File tree

src/audio/module_adapter/library/userspace_proxy.c

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,31 @@ DECLARE_TR_CTX(userspace_proxy_tr, SOF_UUID(userspace_proxy_uuid), LOG_LEVEL_INF
4949

5050
static const struct module_interface userspace_proxy_interface;
5151

52+
#if IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
53+
#include <sof/audio/module_adapter/iadk/system_agent.h>
54+
#include <sof/schedule/dp_schedule.h>
55+
56+
static inline int user_worker_get(void)
57+
{
58+
return 0;
59+
}
60+
static inline void user_worker_put(void) { }
61+
62+
struct k_work_user *userspace_proxy_register_ipc_handler(struct processing_module *mod,
63+
struct k_event *event)
64+
{
65+
struct userspace_context * const user_ctx = mod->user_ctx;
66+
if (user_ctx) {
67+
user_ctx->dp_event = event;
68+
user_ctx->work_item->event = event;
69+
70+
assert(user_ctx->work_item);
71+
return &user_ctx->work_item->work_item;
72+
}
73+
74+
return NULL;
75+
}
76+
#else
5277
/* IPC requests targeting userspace modules are handled through a user work queue.
5378
* Each userspace module provides its own work item that carries the IPC request parameters.
5479
* The worker thread is switched into the module's memory domain and receives the work item.
@@ -106,6 +131,7 @@ static void user_worker_put(void)
106131
user_stack_free(worker.stack_ptr);
107132
}
108133
}
134+
#endif
109135

110136
static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap *user_heap)
111137
{
@@ -128,7 +154,9 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
128154

129155
k_work_user_init(&work_item->work_item, userspace_proxy_worker_handler);
130156

157+
#if !IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
131158
work_item->event = &worker.event;
159+
#endif
132160
work_item->params.context = user_ctx;
133161
user_ctx->work_item = work_item;
134162

@@ -155,14 +183,19 @@ BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_SIZE, CONFIG_MMU_PAGE_SIZE),
155183
static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t cmd,
156184
bool ipc_payload_access)
157185
{
186+
#if IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
187+
struct k_event * const event = user_ctx->dp_event;
188+
#else
189+
struct k_event * const event = &worker.event;
190+
#endif
158191
struct module_params *params = user_work_get_params(user_ctx);
159192
const uintptr_t ipc_req_buf = (uintptr_t)MAILBOX_HOSTBOX_BASE;
160193
struct k_mem_partition ipc_part = {
161194
.start = ipc_req_buf,
162195
.size = MAILBOX_HOSTBOX_SIZE,
163196
.attr = user_get_partition_attr(ipc_req_buf) | K_MEM_PARTITION_P_RO_U_RO,
164197
};
165-
int ret, ret2;
198+
int ret = 0, ret2;
166199

167200
params->cmd = cmd;
168201

@@ -174,6 +207,7 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
174207
}
175208
}
176209

210+
#if !IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
177211
/* Switch worker thread to module memory domain */
178212
ret = k_mem_domain_add_thread(user_ctx->comp_dom, worker.thread_id);
179213
if (ret < 0) {
@@ -193,9 +227,13 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
193227
tr_err(&userspace_proxy_tr, "Submit to queue error: %d", ret);
194228
goto done;
195229
}
230+
#else
231+
assert(event);
232+
k_event_post(event, DP_TASK_EVENT_IPC);
233+
#endif
196234

197235
/* Timeout value is aligned with the ipc_wait_for_compound_msg function */
198-
if (!k_event_wait_safe(&worker.event, DP_TASK_EVENT_IPC_DONE, false,
236+
if (!k_event_wait_safe(event, DP_TASK_EVENT_IPC_DONE, false,
199237
Z_TIMEOUT_US(250 * 20))) {
200238
tr_err(&userspace_proxy_tr, "IPC processing timedout.");
201239
ret = -ETIMEDOUT;
@@ -313,18 +351,27 @@ static int userspace_proxy_start_agent(struct userspace_context *user_ctx,
313351
{
314352
const byte_array_t * const mod_cfg = (byte_array_t *)agent_params->mod_cfg;
315353
struct module_params *params = user_work_get_params(user_ctx);
316-
int ret;
317354

318355
params->ext.agent.start_fn = start_fn;
319-
params->ext.agent.params = *agent_params;
320-
params->ext.agent.mod_cfg = *mod_cfg;
321356

322-
ret = userspace_proxy_invoke(user_ctx, USER_PROXY_MOD_CMD_AGENT_START, true);
323-
if (ret)
324-
return ret;
357+
/* Start the system agent, if provided. */
358+
if (start_fn) {
359+
params->ext.agent.params = *agent_params;
360+
params->ext.agent.mod_cfg = *mod_cfg;
325361

326-
*agent_interface = params->ext.agent.out_interface;
327-
return params->status;
362+
/* In case of processing modules ipc in the DP thread, the agent will be started in the
363+
* init function. At this point the DP thread does not exist yet.
364+
*/
365+
#if !IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
366+
int ret = userspace_proxy_invoke(user_ctx, USER_PROXY_MOD_CMD_AGENT_START, true);
367+
if (ret)
368+
return ret;
369+
370+
*agent_interface = params->ext.agent.out_interface;
371+
return params->status;
372+
#endif
373+
}
374+
return 0;
328375
}
329376

330377
int userspace_proxy_create(struct userspace_context **user_ctx, const struct comp_driver *drv,
@@ -362,14 +409,10 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
362409
if (ret)
363410
goto error_dom;
364411

365-
/* Start the system agent, if provided. */
366-
367-
if (start_fn) {
368-
ret = userspace_proxy_start_agent(context, start_fn, agent_params, agent_interface);
369-
if (ret) {
370-
tr_err(&userspace_proxy_tr, "System agent failed with error %d.", ret);
371-
goto error_work_item;
372-
}
412+
ret = userspace_proxy_start_agent(context, start_fn, agent_params, agent_interface);
413+
if (ret) {
414+
tr_err(&userspace_proxy_tr, "System agent failed with error %d.", ret);
415+
goto error_work_item;
373416
}
374417

375418
*user_ctx = context;
@@ -420,6 +463,22 @@ static int userspace_proxy_init(struct processing_module *mod)
420463

421464
comp_dbg(mod->dev, "start");
422465

466+
#if IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
467+
/* Start the system agent, if provided. Params is already filled by
468+
* the userspace_proxy_start_agent function.
469+
*/
470+
if (params->ext.agent.start_fn) {
471+
ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_AGENT_START, true);
472+
if (ret)
473+
return ret;
474+
475+
if (params->ext.agent.start_fn == system_agent_start)
476+
module_set_private_data(mod, params->ext.agent.out_interface);
477+
else
478+
mod->user_ctx->interface = params->ext.agent.out_interface;
479+
}
480+
#endif
481+
423482
params->mod = mod;
424483
ret = userspace_proxy_invoke(mod->user_ctx, USER_PROXY_MOD_CMD_INIT, true);
425484
if (ret)

src/include/sof/audio/module_adapter/library/userspace_proxy.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct userspace_context {
3131
struct k_mem_domain *comp_dom; /* Module specific memory domain */
3232
const struct module_interface *interface; /* Userspace module interface */
3333
struct user_work_item *work_item; /* work item for user worker thread */
34+
struct k_event *dp_event; /* DP thread event */
3435
};
3536
#endif /* CONFIG_USERSPACE */
3637

@@ -63,6 +64,11 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
6364
*/
6465
void userspace_proxy_destroy(const struct comp_driver *drv, struct userspace_context *user_ctx);
6566

67+
#if IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
68+
struct k_work_user *userspace_proxy_register_ipc_handler(struct processing_module *mod,
69+
struct k_event *event);
70+
#endif
71+
6672
#endif /* CONFIG_SOF_USERSPACE_PROXY */
6773

6874
#endif /* __SOF_AUDIO_USERSPACE_PROXY_H__ */

src/include/sof/audio/module_adapter/library/userspace_proxy_user.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct module_agent_params {
1313
system_agent_start_fn start_fn;
1414
struct system_agent_params params;
1515
byte_array_t mod_cfg;
16-
const void *out_interface;
16+
void *out_interface;
1717
};
1818

1919
struct module_large_cfg_set_params {

src/schedule/zephyr_dp_schedule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum sof_dp_part_type {
3232
};
3333

3434
struct ipc4_flat;
35+
3536
struct task_dp_pdata {
3637
k_tid_t thread_id; /* zephyr thread ID */
3738
struct k_thread *thread; /* pointer to the kernels' thread object */
@@ -49,6 +50,9 @@ struct task_dp_pdata {
4950
#else
5051
struct k_event *event; /* pointer to event for task scheduling */
5152
struct k_event event_struct; /* event for task scheduling for kernel threads */
53+
#if IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
54+
struct k_work_user *ipc_work_item; /* work item for IPC handling */
55+
#endif
5256
#endif
5357
};
5458

src/schedule/zephyr_dp_schedule_thread.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
* Copyright(c) 2025 Intel Corporation. All rights reserved.
44
*
55
* Author: Marcin Szkudlinski
6+
* Adrian Warecki
67
*/
78

89
#include <rtos/task.h>
910

1011
#include <sof/audio/module_adapter/module/generic.h>
1112
#include <sof/audio/module_adapter/library/userspace_proxy.h>
13+
#include <sof/audio/module_adapter/library/userspace_proxy_user.h>
1214
#include <sof/common.h>
1315
#include <sof/list.h>
1416
#include <sof/schedule/ll_schedule_domain.h>
@@ -115,6 +117,7 @@ void dp_thread_fn(void *p1, void *p2, void *p3)
115117
unsigned int lock_key;
116118
enum task_state state;
117119
bool task_stop;
120+
uint32_t event;
118121

119122
if (!(task->flags & K_USER))
120123
dp_sch = scheduler_get_data(SOF_SCHEDULE_DP);
@@ -124,13 +127,22 @@ void dp_thread_fn(void *p1, void *p2, void *p3)
124127
* the thread is started immediately after creation, it will stop on event.
125128
* Event will be signalled once the task is ready to process.
126129
*/
127-
k_event_wait_safe(task_pdata->event, DP_TASK_EVENT_PROCESS | DP_TASK_EVENT_CANCEL,
128-
false, K_FOREVER);
130+
event = k_event_wait_safe(task_pdata->event, DP_TASK_EVENT_PROCESS |
131+
DP_TASK_EVENT_CANCEL | DP_TASK_EVENT_IPC, false,
132+
K_FOREVER);
129133

130-
if (task->state == SOF_TASK_STATE_RUNNING)
131-
state = task_run(task);
132-
else
133-
state = task->state; /* to avoid undefined variable warning */
134+
state = task->state; /* to avoid undefined variable warning */
135+
if (task->state == SOF_TASK_STATE_RUNNING) {
136+
switch (event) {
137+
case DP_TASK_EVENT_PROCESS:
138+
state = task_run(task);
139+
break;
140+
case DP_TASK_EVENT_IPC:
141+
assert(task_pdata->ipc_work_item);
142+
userspace_proxy_worker_handler(task_pdata->ipc_work_item);
143+
continue;
144+
}
145+
}
134146

135147
lock_key = scheduler_dp_lock(task->core);
136148
/*
@@ -294,6 +306,11 @@ int scheduler_dp_task_init(struct task **task,
294306
k_event_init(pdata->event);
295307
k_thread_start(pdata->thread_id);
296308

309+
#if IS_ENABLED(CONFIG_SOF_USERSPACE_PROXY) && \
310+
IS_ENABLED(CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD)
311+
pdata->ipc_work_item = userspace_proxy_register_ipc_handler(mod, pdata->event);
312+
#endif
313+
297314
/* success, fill output parameter */
298315
*task = &task_memory->task;
299316
return 0;

0 commit comments

Comments
 (0)