-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pipeline: fail to recover from xrun in pipeline_task #2926
pipeline: fail to recover from xrun in pipeline_task #2926
Conversation
What steps will reproduce the problem?
What is the expected output? What do you see instead? How frequently does this problem reproduce? (Always, sometimes, hard to HW: Chromebook Fleex (GLK) According to the trace, the pipeline_task() tries to recover the xrun but fail because the pipeline state is in active so pipeline_prepare fails.
This log is captured from patched FW. It recovers from underrun and the audio stream does not break. I can hear the audio from HDMI output.
Regards, |
There used to be in-firmware code for doing this recovery. Recently the responsibility has been shifted to the userspace to do said recovery. Whenever this happens, does refreshing the YouTube page recover the xrun? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pipeline_task() just returns and the host driver seems not being aware of it. CRAS tries to resolve it by sending more data but not working since the pipeline is already closed in SOF side. User needs to restart the Youtube page so the pcm device will be open again. One thing I'd like to point out is that this patch is targeting glk-012-stable-branch instead of master. |
Before merging this, we should tag current top as some X.0 glk release and then this as X.1. We shouldn't just push to stable branches. |
Hi Keyon, I didn't observe recovery in kernel level. Should it be done in application? Regards, 2020-05-19T09:40:36.179748+08:00 DEBUG kernel: [ 313.030148] sound pcmC0D5p: snd_pcm_common_ioctl: START |
@brentlu I want to understand what really going, can you explain why the xrun(underrun?) happen here? does the CRAS stop sending data when the monitor is turned off? @kv2019i @libinyang IIRC, our DP/HDMI supports silent playback(e.g. even the monitor is turned off, we will keep sending audio samples to i915...)? |
Hi Keyon, I think it's not related to silent playback. When monitor is turned off, CRAS switches path to speaker so it closes the PCM device of HDMI (pcmC0D5p). When the monitor is turned on, CRAS will open the HDMI PCM device again and starts sending data. Regards, |
On 5/19/20 10:47 AM, Brent Lu wrote:
Hi Keyon,
I think it's not related to silent playback. When monitor is turned off, CRAS switches path to speaker so it closes the PCM device of HDMI (pcmC0D5p). When the monitor is turned on, CRAS will open the HDMI PCM device again and starts sending data.
Oh, that makes sense, then why Xrun happen if the pcmC0D5p is already
closed?
~Keyon
…
Regards,
Brent
|
Hi Keyon, According to the log, the underrun happens after it got the START trigger so I think the pcm device is opened on the Linux side. 0 2 DAI 5.31 162569273.489583 3.072917 src/audio/dai.c:519 dai_comp_trigger(), START From the Linux log, it seems SOF reads only 96 samples then stops working. |
On 5/19/20 11:15 AM, Brent Lu wrote:
Hi Keyon,
According to the log, the underrun happens after it got the START trigger so I think the pcm device is opened on the Linux side.
0 2 DAI 5.31 162569273.489583 3.072917 src/audio/dai.c:519 dai_comp_trigger(), START
0 1 DMA 162569488.854167 215.364578 intel/cavs/hda-dma.c:284 hda-dmac: 5 wait for buffer full timeout
…
>From the Linux log, it seems SOF reads only 96 samples then stops working.
2020-05-19T09:40:36.179752+08:00 DEBUG kernel: [ 313.030162] sof-audio-pci 0000:00:0e.0: ipc tx: 0x60040000: GLB_STREAM_MSG: TRIG_START
=> START trigger sent to FW
2020-05-19T09:40:36.179757+08:00 DEBUG kernel: [ 313.030631] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 4096 avail 12368
=> 4K sample written by CRAS, 96 read by SOF
...
...
2020-05-19T09:40:36.351035+08:00 DEBUG kernel: [ 313.201585] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0
=> buffer full, still 96 read by SOF
|
Hi Keyon, The patched firmware isn't working even for non-hda playback. Maybe there is more patches to merge. 347ee08 hda-dma: change preload from blocking to repeating Regards, |
oops, then the solution taking should be up to you @jajanusz @mrajwa. If we can figure out a fix with backporting commits from the master branch, it will be easier for maintaining. |
Entire pipeline preload has been removed. Backporting the current solution is almost impossible. |
Hi, Just wondering if this patch will be merged because customer is asking. Thanks. Regards, |
Hi, We've got escalated by customer for this issue. Is there any progress? Thanks. |
@brentlu can you clarify for me what is different from what you reported on the alsa-devel mailing list:
Is this needed in addition to the RIRB fix at the kernel level? |
Hi Pierre, They are different issues although the result is the same: no audio output. The RIRB issue happens in PREPARE stage when host sending verbs to codec. |
ok, thanks for the precision @brentlu |
Since negative error code returned by the t/o'ed host component triggers pipeline_xrun_recover() while components are in active state, so this flow would always result in failure and must be fixed. However a component (host in this case) is expected to call comp_underrun() upon detecting underrun (atm only dai does it). comp_underrun() calls pipeline_xrun() which triggers required state transition (forced by the stop trigger in the proposed solution). |
@mrajwa the resource is allocated in .params so if I insert an .reset here then next .prepare will fail
And the kernel is Chrome 4.14 which is pretty outdated. FW is 'glk-012-stable-branch' branch which is behind master for around 2200+ commits... Regards, |
Calling comp_underrun() in host component to recover from XRUN caused by preload fail. Signed-off-by: Brent Lu <brent.lu@intel.com>
8a2ef6f
to
0f9e928
Compare
This is better but lacks a check for direction: diff --git a/src/audio/host.c b/src/audio/host.c
index 9b85d931..b214df8f 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -790,6 +790,12 @@ static int host_copy(struct comp_dev *dev)
if (ret < 0) {
trace_host_error("host_copy() error: dma_copy() "
"failed, ret = %u", ret);
+
+ if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK)
+ comp_underrun(dev, hd->dma_buffer, hd->dma_buffer->size, 0);
+ else
+ comp_overrun(dev, hd->dma_buffer, hd->dma_buffer->size, 0);
+
return ret;
}
} |
The pipeline is in active state so pipeline_prepare() always fail and
the pipeline_task() stops the pipeline. A stop trigger could move the
pipeline to prepare state for pipeline_prepare() to run successfully.
Signed-off-by: Brent Lu brent.lu@intel.com