Skip to content

Commit c7d0149

Browse files
committed
pipeline: fix tasks initialization
Fixes tasks initialization for connected pipelines. If we play on pipeline, which is not the owner of the scheduling component, then the pipeline_prepare() is not called on pipe owning that component and tasks stay unitialized. Fixes: de7d4c9 ("pipeline: allocate pipe_task only if needed") Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent 66b0a0f commit c7d0149

File tree

1 file changed

+60
-49
lines changed

1 file changed

+60
-49
lines changed

src/audio/pipeline.c

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,62 @@ int pipeline_params(struct pipeline *p, struct comp_dev *host,
350350
return ret;
351351
}
352352

353+
static struct task *pipeline_task_init(struct pipeline *p, uint32_t type,
354+
enum task_state (*func)(void *data))
355+
{
356+
struct task *task = NULL;
357+
358+
task = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, sizeof(*task));
359+
360+
if (task)
361+
schedule_task_init(task, type, p->ipc_pipe.priority, func, NULL,
362+
p, p->ipc_pipe.core, 0);
363+
364+
return task;
365+
}
366+
367+
static int pipeline_comp_task_init(struct pipeline *p)
368+
{
369+
uint32_t type;
370+
371+
/* pipeline preload needed only for playback streams without active
372+
* sink component (it can be active for e.g. mixer pipelines)
373+
*/
374+
p->preload =
375+
p->sink_comp->params.direction == SOF_IPC_STREAM_PLAYBACK &&
376+
p->sink_comp->state != COMP_STATE_ACTIVE;
377+
378+
/* initialize task if necessary */
379+
if (!p->pipe_task) {
380+
/* right now we always consider pipeline as a low latency
381+
* component, but it may change in the future
382+
*/
383+
type = pipeline_is_timer_driven(p) ? SOF_SCHEDULE_LL_TIMER :
384+
SOF_SCHEDULE_LL_DMA;
385+
386+
p->pipe_task = pipeline_task_init(p, type, pipeline_task);
387+
if (!p->pipe_task) {
388+
trace_pipe_error("pipeline_prepare() error: task init "
389+
"failed");
390+
return -ENOMEM;
391+
}
392+
}
393+
394+
/* initialize preload task if necessary */
395+
if (p->preload && !p->preload_task) {
396+
/* preload task is always EDF as it guarantees scheduling */
397+
p->preload_task = pipeline_task_init(p, SOF_SCHEDULE_EDF,
398+
pipeline_preload_task);
399+
if (!p->preload_task) {
400+
trace_pipe_error("pipeline_prepare() error: preload "
401+
"task init failed");
402+
return -ENOMEM;
403+
}
404+
}
405+
406+
return 0;
407+
}
408+
353409
static int pipeline_comp_prepare(struct comp_dev *current, void *data, int dir)
354410
{
355411
int err = 0;
@@ -381,6 +437,10 @@ static int pipeline_comp_prepare(struct comp_dev *current, void *data, int dir)
381437
}
382438
}
383439

440+
err = pipeline_comp_task_init(current->pipeline);
441+
if (err < 0)
442+
return err;
443+
384444
err = comp_prepare(current);
385445
if (err < 0 || err == PPL_STATUS_PATH_STOP)
386446
return err;
@@ -389,25 +449,10 @@ static int pipeline_comp_prepare(struct comp_dev *current, void *data, int dir)
389449
&buffer_reset_pos, dir);
390450
}
391451

392-
static struct task *pipeline_task_init(struct pipeline *p, uint32_t type,
393-
enum task_state (*func)(void *data))
394-
{
395-
struct task *task = NULL;
396-
397-
task = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, sizeof(*task));
398-
399-
if (task)
400-
schedule_task_init(task, type, p->ipc_pipe.priority, func, NULL,
401-
p, p->ipc_pipe.core, 0);
402-
403-
return task;
404-
}
405-
406452
/* prepare the pipeline for usage - preload host buffers here */
407453
int pipeline_prepare(struct pipeline *p, struct comp_dev *dev)
408454
{
409455
struct pipeline_data ppl_data;
410-
uint32_t type;
411456
int ret = 0;
412457

413458
trace_pipe_with_ids(p, "pipeline_prepare()");
@@ -421,40 +466,6 @@ int pipeline_prepare(struct pipeline *p, struct comp_dev *dev)
421466
return ret;
422467
}
423468

424-
/* pipeline preload needed only for playback streams without active
425-
* sink component (it can be active for e.g. mixer pipelines)
426-
*/
427-
p->preload = dev->params.direction == SOF_IPC_STREAM_PLAYBACK &&
428-
p->sink_comp->state != COMP_STATE_ACTIVE;
429-
430-
/* initialize task if necessary */
431-
if (!p->pipe_task) {
432-
/* right now we always consider pipeline as a low latency
433-
* component, but it may change in the future
434-
*/
435-
type = pipeline_is_timer_driven(p) ? SOF_SCHEDULE_LL_TIMER :
436-
SOF_SCHEDULE_LL_DMA;
437-
438-
p->pipe_task = pipeline_task_init(p, type, pipeline_task);
439-
if (!p->pipe_task) {
440-
trace_pipe_error("pipeline_prepare() error: task init "
441-
"failed");
442-
return -ENOMEM;
443-
}
444-
}
445-
446-
/* initialize preload task if necessary */
447-
if (p->preload && !p->preload_task) {
448-
/* preload task is always EDF as it guarantees scheduling */
449-
p->preload_task = pipeline_task_init(p, SOF_SCHEDULE_EDF,
450-
pipeline_preload_task);
451-
if (!p->preload_task) {
452-
trace_pipe_error("pipeline_prepare() error: preload "
453-
"task init failed");
454-
return -ENOMEM;
455-
}
456-
}
457-
458469
p->status = COMP_STATE_PREPARE;
459470

460471
return ret;

0 commit comments

Comments
 (0)