diff options
author | Takashi Iwai <tiwai@suse.de> | 2020-11-23 09:53:32 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2020-11-23 15:15:26 +0100 |
commit | c15871e17fc6efb98176b92b4152019876dbec24 (patch) | |
tree | 23798581450b05f5f8b4dcd311cc67f9b203ed9f /sound/usb/card.h | |
parent | bf6313a0ff766925462e97b4e733d5952de02367 (diff) | |
download | linux-c15871e17fc6efb98176b92b4152019876dbec24.tar.bz2 |
ALSA: usb-audio: Fix possible stall of implicit fb packet ring-buffer
The implicit feedback mode uses a ring buffer for storing the received
packet sizes from the feedback source, and the code has a slight flaw;
when a playback stream stalls by some reason and the URBs aren't
processed, the next_packet FIFO might become empty, but the driver
can't distinguish whether it's empty or full because it's managed with
read_poss and write_pos.
This patch addresses those by changing the next_packet array
management. Instead of keeping read and write positions, now the head
position and the queued amount are kept. It's easier to understand
about the emptiness. Also, the URB active flag is now cleared before
calling queue_pending_output_urbs() for avoiding (theoretically)
possible inconsistency.
Tested-by: Keith Milner <kamilner@superlative.org>
Tested-by: Dylan Robinson <dylan_robinson@motu.com>
Link: https://lore.kernel.org/r/20201123085347.19667-27-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/card.h')
-rw-r--r-- | sound/usb/card.h | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index 66a249ae138f..cde492e9581a 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -80,8 +80,9 @@ struct snd_usb_endpoint { uint32_t packet_size[MAX_PACKS_HS]; int packets; } next_packet[MAX_URBS]; - int next_packet_read_pos, next_packet_write_pos; - struct list_head ready_playback_urbs; + unsigned int next_packet_head; /* ring buffer offset to read */ + unsigned int next_packet_queued; /* queued items in the ring buffer */ + struct list_head ready_playback_urbs; /* playback URB FIFO for implicit fb */ unsigned int nurbs; /* # urbs */ unsigned long active_mask; /* bitmask of active urbs */ |