Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+63 -25
+3 -2
sound/usb/card.h
··· 80 80 uint32_t packet_size[MAX_PACKS_HS]; 81 81 int packets; 82 82 } next_packet[MAX_URBS]; 83 - int next_packet_read_pos, next_packet_write_pos; 84 - struct list_head ready_playback_urbs; 83 + unsigned int next_packet_head; /* ring buffer offset to read */ 84 + unsigned int next_packet_queued; /* queued items in the ring buffer */ 85 + struct list_head ready_playback_urbs; /* playback URB FIFO for implicit fb */ 85 86 86 87 unsigned int nurbs; /* # urbs */ 87 88 unsigned long active_mask; /* bitmask of active urbs */
+60 -23
sound/usb/endpoint.c
··· 328 328 } 329 329 } 330 330 331 + /* notify an error as XRUN to the assigned PCM data substream */ 332 + static void notify_xrun(struct snd_usb_endpoint *ep) 333 + { 334 + struct snd_usb_substream *data_subs; 335 + 336 + data_subs = READ_ONCE(ep->data_subs); 337 + if (data_subs && data_subs->pcm_substream) 338 + snd_pcm_stop_xrun(data_subs->pcm_substream); 339 + } 340 + 341 + static struct snd_usb_packet_info * 342 + next_packet_fifo_enqueue(struct snd_usb_endpoint *ep) 343 + { 344 + struct snd_usb_packet_info *p; 345 + 346 + p = ep->next_packet + (ep->next_packet_head + ep->next_packet_queued) % 347 + ARRAY_SIZE(ep->next_packet); 348 + ep->next_packet_queued++; 349 + return p; 350 + } 351 + 352 + static struct snd_usb_packet_info * 353 + next_packet_fifo_dequeue(struct snd_usb_endpoint *ep) 354 + { 355 + struct snd_usb_packet_info *p; 356 + 357 + p = ep->next_packet + ep->next_packet_head; 358 + ep->next_packet_head++; 359 + ep->next_packet_head %= ARRAY_SIZE(ep->next_packet); 360 + ep->next_packet_queued--; 361 + return p; 362 + } 363 + 331 364 /* 332 365 * Send output urbs that have been prepared previously. URBs are dequeued 333 366 * from ep->ready_playback_urbs and in case there aren't any available ··· 385 352 int err, i; 386 353 387 354 spin_lock_irqsave(&ep->lock, flags); 388 - if (ep->next_packet_read_pos != ep->next_packet_write_pos) { 389 - packet = ep->next_packet + ep->next_packet_read_pos; 390 - ep->next_packet_read_pos++; 391 - ep->next_packet_read_pos %= MAX_URBS; 392 - 355 + if (ep->next_packet_queued > 0 && 356 + !list_empty(&ep->ready_playback_urbs)) { 393 357 /* take URB out of FIFO */ 394 - if (!list_empty(&ep->ready_playback_urbs)) { 395 - ctx = list_first_entry(&ep->ready_playback_urbs, 358 + ctx = list_first_entry(&ep->ready_playback_urbs, 396 359 struct snd_urb_ctx, ready_list); 397 - list_del_init(&ctx->ready_list); 398 - } 360 + list_del_init(&ctx->ready_list); 361 + 362 + packet = next_packet_fifo_dequeue(ep); 399 363 } 400 364 spin_unlock_irqrestore(&ep->lock, flags); 401 365 ··· 407 377 prepare_outbound_urb(ep, ctx); 408 378 409 379 err = usb_submit_urb(ctx->urb, GFP_ATOMIC); 410 - if (err < 0) 380 + if (err < 0) { 411 381 usb_audio_err(ep->chip, 412 382 "Unable to submit urb #%d: %d at %s\n", 413 383 ctx->index, err, __func__); 414 - else 415 - set_bit(ctx->index, &ep->active_mask); 384 + notify_xrun(ep); 385 + return; 386 + } 387 + 388 + set_bit(ctx->index, &ep->active_mask); 416 389 } 417 390 } 418 391 ··· 426 393 { 427 394 struct snd_urb_ctx *ctx = urb->context; 428 395 struct snd_usb_endpoint *ep = ctx->ep; 429 - struct snd_usb_substream *data_subs; 430 396 unsigned long flags; 431 397 int err; 432 398 ··· 450 418 if (snd_usb_endpoint_implicit_feedback_sink(ep)) { 451 419 spin_lock_irqsave(&ep->lock, flags); 452 420 list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); 421 + clear_bit(ctx->index, &ep->active_mask); 453 422 spin_unlock_irqrestore(&ep->lock, flags); 454 423 queue_pending_output_urbs(ep); 455 - 456 - goto exit_clear; 424 + return; 457 425 } 458 426 459 427 prepare_outbound_urb(ep, ctx); ··· 474 442 return; 475 443 476 444 usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); 477 - data_subs = READ_ONCE(ep->data_subs); 478 - if (data_subs && data_subs->pcm_substream) 479 - snd_pcm_stop_xrun(data_subs->pcm_substream); 445 + notify_xrun(ep); 480 446 481 447 exit_clear: 482 448 clear_bit(ctx->index, &ep->active_mask); ··· 819 789 clear_bit(EP_FLAG_RUNNING, &ep->flags); 820 790 821 791 INIT_LIST_HEAD(&ep->ready_playback_urbs); 822 - ep->next_packet_read_pos = 0; 823 - ep->next_packet_write_pos = 0; 792 + ep->next_packet_head = 0; 793 + ep->next_packet_queued = 0; 824 794 825 795 for (i = 0; i < ep->nurbs; i++) { 826 796 if (test_bit(i, &ep->active_mask)) { ··· 1432 1402 return; 1433 1403 1434 1404 spin_lock_irqsave(&ep->lock, flags); 1435 - out_packet = ep->next_packet + ep->next_packet_write_pos; 1405 + if (ep->next_packet_queued >= ARRAY_SIZE(ep->next_packet)) { 1406 + spin_unlock_irqrestore(&ep->lock, flags); 1407 + usb_audio_err(ep->chip, 1408 + "next package FIFO overflow EP 0x%x\n", 1409 + ep->ep_num); 1410 + notify_xrun(ep); 1411 + return; 1412 + } 1413 + 1414 + out_packet = next_packet_fifo_enqueue(ep); 1436 1415 1437 1416 /* 1438 1417 * Iterate through the inbound packet and prepare the lengths ··· 1462 1423 out_packet->packet_size[i] = 0; 1463 1424 } 1464 1425 1465 - ep->next_packet_write_pos++; 1466 - ep->next_packet_write_pos %= MAX_URBS; 1467 1426 spin_unlock_irqrestore(&ep->lock, flags); 1468 1427 queue_pending_output_urbs(ep); 1469 1428