]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 May 2020 11:12:29 +0000 (13:12 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 May 2020 11:12:29 +0000 (13:12 +0200)
added patches:
alsa-pcm-fix-incorrect-hw_base-increase.patch

queue-4.9/alsa-pcm-fix-incorrect-hw_base-increase.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/alsa-pcm-fix-incorrect-hw_base-increase.patch b/queue-4.9/alsa-pcm-fix-incorrect-hw_base-increase.patch
new file mode 100644 (file)
index 0000000..784415d
--- /dev/null
@@ -0,0 +1,80 @@
+From e7513c5786f8b33f0c107b3759e433bc6cbb2efa Mon Sep 17 00:00:00 2001
+From: Brent Lu <brent.lu@intel.com>
+Date: Mon, 18 May 2020 12:30:38 +0800
+Subject: ALSA: pcm: fix incorrect hw_base increase
+
+From: Brent Lu <brent.lu@intel.com>
+
+commit e7513c5786f8b33f0c107b3759e433bc6cbb2efa upstream.
+
+There is a corner case that ALSA keeps increasing the hw_ptr but DMA
+already stop working/updating the position for a long time.
+
+In following log we can see the position returned from DMA driver does
+not move at all but the hw_ptr got increased at some point of time so
+snd_pcm_avail() will return a large number which seems to be a buffer
+underrun event from user space program point of view. The program
+thinks there is space in the buffer and fill more data.
+
+[  418.510086] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 4096 avail 12368
+[  418.510149] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 6910 avail 9554
+...
+[  418.681052] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 15102 avail 1362
+[  418.681130] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0
+[  418.726515] sound pcmC0D5p: pos 96 hw_ptr 16464 appl_ptr 16464 avail 16368
+
+This is because the hw_base will be increased by runtime->buffer_size
+frames unconditionally if the hw_ptr is not updated for over half of
+buffer time. As the hw_base increases, so does the hw_ptr increased
+by the same number.
+
+The avail value returned from snd_pcm_avail() could exceed the limit
+(buffer_size) easily becase the hw_ptr itself got increased by same
+buffer_size samples when the corner case happens. In following log,
+the buffer_size is 16368 samples but the avail is 21810 samples so
+CRAS server complains about it.
+
+[  418.851755] sound pcmC0D5p: pos 96 hw_ptr 16464 appl_ptr 27390 avail 5442
+[  418.926491] sound pcmC0D5p: pos 96 hw_ptr 32832 appl_ptr 27390 avail 21810
+
+cras_server[1907]: pcm_avail returned frames larger than buf_size:
+sof-glkda7219max: :0,5: 21810 > 16368
+
+By updating runtime->hw_ptr_jiffies each time the HWSYNC is called,
+the hw_base will keep the same when buffer stall happens at long as
+the interval between each HWSYNC call is shorter than half of buffer
+time.
+
+Following is a log captured by a patched kernel. The hw_base/hw_ptr
+value is fixed in this corner case and user space program should be
+aware of the buffer stall and handle it.
+
+[  293.525543] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 4096 avail 12368
+[  293.525606] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 6880 avail 9584
+[  293.525975] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 10976 avail 5488
+[  293.611178] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 15072 avail 1392
+[  293.696429] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0
+...
+[  381.139517] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0
+
+Signed-off-by: Brent Lu <brent.lu@intel.com>
+Reviewed-by: Jaroslav Kysela <perex@perex.cz>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1589776238-23877-1-git-send-email-brent.lu@intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/pcm_lib.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -456,6 +456,7 @@ static int snd_pcm_update_hw_ptr0(struct
+  no_delta_check:
+       if (runtime->status->hw_ptr == new_hw_ptr) {
++              runtime->hw_ptr_jiffies = curr_jiffies;
+               update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
+               return 0;
+       }
index 86e9848cf8028c91c240d5f637a91465d4bb4f85..4f88fd8139874483776ee05bdb9bcb53dcad50a8 100644 (file)
@@ -46,3 +46,4 @@ l2tp-don-t-register-sessions-in-l2tp_session_create.patch
 l2tp-initialise-l2tp_eth-sessions-before-registering-them.patch
 l2tp-protect-sock-pointer-of-struct-pppol2tp_session-with-rcu.patch
 l2tp-initialise-ppp-sessions-before-registering-them.patch
+alsa-pcm-fix-incorrect-hw_base-increase.patch