Skip to content

Commit 1ee23fe

Browse files
committed
ALSA: usb-audio: Fix deadlocks at resuming
The recent addition of the USB audio mixer suspend/resume may lead to deadlocks when the driver tries to call usb_autopm_get_interface() recursively, since the function tries to sync with the finish of the other calls. For avoiding it, introduce a flag indicating the resume operation and avoids the recursive usb_autopm_get_interface() calls during the resume. Reported-and-tested-by: Bryan Quigley <[email protected]> Signed-off-by: Takashi Iwai <[email protected]>
1 parent 1c53e72 commit 1ee23fe

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

sound/usb/card.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
651651
int err = -ENODEV;
652652

653653
down_read(&chip->shutdown_rwsem);
654-
if (chip->probing)
654+
if (chip->probing && chip->in_pm)
655655
err = 0;
656656
else if (!chip->shutdown)
657657
err = usb_autopm_get_interface(chip->pm_intf);
@@ -663,7 +663,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
663663
void snd_usb_autosuspend(struct snd_usb_audio *chip)
664664
{
665665
down_read(&chip->shutdown_rwsem);
666-
if (!chip->shutdown && !chip->probing)
666+
if (!chip->shutdown && !chip->probing && !chip->in_pm)
667667
usb_autopm_put_interface(chip->pm_intf);
668668
up_read(&chip->shutdown_rwsem);
669669
}
@@ -712,6 +712,8 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
712712
return 0;
713713
if (--chip->num_suspended_intf)
714714
return 0;
715+
716+
chip->in_pm = 1;
715717
/*
716718
* ALSA leaves material resumption to user space
717719
* we just notify and restart the mixers
@@ -727,6 +729,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
727729
chip->autosuspended = 0;
728730

729731
err_out:
732+
chip->in_pm = 0;
730733
return err;
731734
}
732735

sound/usb/usbaudio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct snd_usb_audio {
4040
struct rw_semaphore shutdown_rwsem;
4141
unsigned int shutdown:1;
4242
unsigned int probing:1;
43+
unsigned int in_pm:1;
4344
unsigned int autosuspended:1;
4445
unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
4546

0 commit comments

Comments
 (0)