mirror of https://github.com/thesofproject/sof.git
pipeline: fix aborting STOP or PAUSE propagation
When trigger.aborted is set, pipeline_trigger_run() also returns PPL_STATUS_PATH_STOP. So the current test for trigger.aborted in pipeline_task_cmd() after pipeline_trigger_run() is a left-over from an earlier implementation and is never entered with the current flow. In the current implementation, a typical playback topology like [pipeline A] PCM -> ... - [pipeline B] mixer -> ... -> DAI when a pause is triggered mixer will stop its propagation, set trigger.aborted on pipeline B to true and return PPL_STATUS_PATH_STOP. pipeline_task_cmd() is still running in the context of pipeline A, so it will detect PPL_STATUS_PATH_STOP, check that trigger.aborted is not set and terminate the task. Then the scheduler will run the task for pipeline B, that one will verify, that trigger.host == NULL, then find the trigger.aborted to be true and will keep the task running. In a topology, where the PCM, the mixer and the DAI all belong to the same pipeline, when PAUSE is triggered, the whole pipeline should be left running which is what this patch achieves by checkint trigger.aborted when PPL_STATUS_PATH_STOP is returned by pipeline_trigger_run(). BugLink: https://github.com/thesofproject/sof/issues/5257 Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
parent
8b519858c5
commit
c04b7fc13e
|
@ -81,15 +81,7 @@ static enum task_state pipeline_task_cmd(struct pipeline *p,
|
||||||
|
|
||||||
if (err == PPL_STATUS_PATH_STOP) {
|
if (err == PPL_STATUS_PATH_STOP) {
|
||||||
/* comp_trigger() interrupted trigger propagation or an xrun occurred */
|
/* comp_trigger() interrupted trigger propagation or an xrun occurred */
|
||||||
err = SOF_TASK_STATE_COMPLETED;
|
if (p->trigger.aborted && p->status == COMP_STATE_PAUSED) {
|
||||||
} else if (p->trigger.cmd != cmd) {
|
|
||||||
/* PRE stage completed */
|
|
||||||
if (p->trigger.delay)
|
|
||||||
return SOF_TASK_STATE_RESCHEDULE;
|
|
||||||
/* No delay: the final stage has already run too */
|
|
||||||
err = SOF_TASK_STATE_RESCHEDULE;
|
|
||||||
} else if (p->status == COMP_STATE_PAUSED) {
|
|
||||||
if (p->trigger.aborted) {
|
|
||||||
p->status = COMP_STATE_ACTIVE;
|
p->status = COMP_STATE_ACTIVE;
|
||||||
/*
|
/*
|
||||||
* the pipeline aborted a STOP or a PAUSE
|
* the pipeline aborted a STOP or a PAUSE
|
||||||
|
@ -99,6 +91,14 @@ static enum task_state pipeline_task_cmd(struct pipeline *p,
|
||||||
} else {
|
} else {
|
||||||
err = SOF_TASK_STATE_COMPLETED;
|
err = SOF_TASK_STATE_COMPLETED;
|
||||||
}
|
}
|
||||||
|
} else if (p->trigger.cmd != cmd) {
|
||||||
|
/* PRE stage completed */
|
||||||
|
if (p->trigger.delay)
|
||||||
|
return SOF_TASK_STATE_RESCHEDULE;
|
||||||
|
/* No delay: the final stage has already run too */
|
||||||
|
err = SOF_TASK_STATE_RESCHEDULE;
|
||||||
|
} else if (p->status == COMP_STATE_PAUSED) {
|
||||||
|
err = SOF_TASK_STATE_COMPLETED;
|
||||||
} else {
|
} else {
|
||||||
p->status = COMP_STATE_ACTIVE;
|
p->status = COMP_STATE_ACTIVE;
|
||||||
err = SOF_TASK_STATE_RESCHEDULE;
|
err = SOF_TASK_STATE_RESCHEDULE;
|
||||||
|
|
Loading…
Reference in New Issue