-
Notifications
You must be signed in to change notification settings - Fork 349
Description
I found this IPC scheduling and dependency issue while troubleshooting DMA traces on Zephyr but I suspect it has consequences even without Zephyr. In fact I wonder whether it could maybe explain the very long standing #4333 "lag" in DMA traces too.
In Zephyr the problem is simple (once you know it!): no (legacy) EDF scheduler -> task_main_primary_core does not run -> no IPC TX flush -> no DMA traces.
enum task_state task_main_primary_core(void *data)
{
/* main audio processing loop */
while (1) {
/* sleep until next IPC or DMA */
wait_for_interrupt(0);
if (!ipc->pm_prepare_D3)
ipc_send_queued_msg();
}
}I tried to schedule task_main_primary_core() in Zephyr too but I hit the following circular dependency with the EDF scheduler where the EDF scheduler wants to initialize the main task in the middle of its own initialization and task_main_init() needs the half-initialized EDF scheduler to schedule itself.
int scheduler_init_edf(void)
{
edf_sch = rzalloc(SOF_MEM_ZONE_SYS, 0, SOF_MEM_CAPS_RAM,
sizeof(*edf_sch));
scheduler_init(SOF_SCHEDULE_EDF, &schedule_edf_ops, edf_sch);
/* initialize AND SCHEDULE main task context before enabling interrupt */
task_main_init();
interrupt_enable(edf_sch->irq, edf_sch);
}Here's one super-ugly and probably unreliable workaround. Warning: many other code changes are required to get DMA traces with Zephyr.
--- a/src/trace/dma-trace.c
+++ b/src/trace/dma-trace.c
@@ -379,7 +379,7 @@ static int dma_trace_get_avail_data(struct dma_trace_data *d,
* if no new trace is filled.
*/
if (d->old_host_offset != d->posn.host_offset) {
- ipc_msg_send(d->msg, &d->posn, false);
+ ipc_msg_send(d->msg, &d->posn, true /* try to send immediately */ );
Even in plain SOF, this does not "feel right" and as I wrote above I wonder whether it could explain the very regular DMA traces "lag" exposed in #4333
The circular dependency and all the code above is as old as the entire scheduler itself: Aug 2019 20acc16 in giant PR #1710
There was a small ipc_send_queued_msg() refactor in Feb 2020 commit 9e0b2e5 but I don't think it changed the logic.