| From adc8a43a6d6688272ebffa81789fa857e603dec6 Mon Sep 17 00:00:00 2001 |
| From: Andrej Krutak <dev@andree.sk> |
| Date: Thu, 18 Aug 2016 23:52:11 +0200 |
| Subject: ALSA: line6: Give up on the lock while URBs are released. |
| |
| From: Andrej Krutak <dev@andree.sk> |
| |
| commit adc8a43a6d6688272ebffa81789fa857e603dec6 upstream. |
| |
| Done, because line6_stream_stop() locks and calls line6_unlink_audio_urbs(), |
| which in turn invokes audio_out_callback(), which tries to lock 2nd time. |
| |
| Fixes: |
| |
| ============================================= |
| [ INFO: possible recursive locking detected ] |
| 4.4.15+ #15 Not tainted |
| --------------------------------------------- |
| mplayer/3591 is trying to acquire lock: |
| (&(&line6pcm->out.lock)->rlock){-.-...}, at: [<bfa27655>] audio_out_callback+0x70/0x110 [snd_usb_line6] |
| |
| but task is already holding lock: |
| (&(&line6pcm->out.lock)->rlock){-.-...}, at: [<bfa26aad>] line6_stream_stop+0x24/0x5c [snd_usb_line6] |
| |
| other info that might help us debug this: |
| Possible unsafe locking scenario: |
| |
| CPU0 |
| ---- |
| lock(&(&line6pcm->out.lock)->rlock); |
| lock(&(&line6pcm->out.lock)->rlock); |
| |
| *** DEADLOCK *** |
| |
| May be due to missing lock nesting notation |
| |
| 3 locks held by mplayer/3591: |
| #0: (snd_pcm_link_rwlock){.-.-..}, at: [<bf8d49a7>] snd_pcm_stream_lock+0x1e/0x40 [snd_pcm] |
| #1: (&(&substream->self_group.lock)->rlock){-.-...}, at: [<bf8d49af>] snd_pcm_stream_lock+0x26/0x40 [snd_pcm] |
| #2: (&(&line6pcm->out.lock)->rlock){-.-...}, at: [<bfa26aad>] line6_stream_stop+0x24/0x5c [snd_usb_line6] |
| |
| stack backtrace: |
| CPU: 0 PID: 3591 Comm: mplayer Not tainted 4.4.15+ #15 |
| Hardware name: Generic AM33XX (Flattened Device Tree) |
| [<c0015d85>] (unwind_backtrace) from [<c001253d>] (show_stack+0x11/0x14) |
| [<c001253d>] (show_stack) from [<c02f1bdf>] (dump_stack+0x8b/0xac) |
| [<c02f1bdf>] (dump_stack) from [<c0076f43>] (__lock_acquire+0xc8b/0x1780) |
| [<c0076f43>] (__lock_acquire) from [<c007810d>] (lock_acquire+0x99/0x1c0) |
| [<c007810d>] (lock_acquire) from [<c06171e7>] (_raw_spin_lock_irqsave+0x3f/0x4c) |
| [<c06171e7>] (_raw_spin_lock_irqsave) from [<bfa27655>] (audio_out_callback+0x70/0x110 [snd_usb_line6]) |
| [<bfa27655>] (audio_out_callback [snd_usb_line6]) from [<c04294db>] (__usb_hcd_giveback_urb+0x53/0xd0) |
| [<c04294db>] (__usb_hcd_giveback_urb) from [<c046388d>] (musb_giveback+0x3d/0x98) |
| [<c046388d>] (musb_giveback) from [<c04647f5>] (musb_urb_dequeue+0x6d/0x114) |
| [<c04647f5>] (musb_urb_dequeue) from [<c042ac11>] (usb_hcd_unlink_urb+0x39/0x98) |
| [<c042ac11>] (usb_hcd_unlink_urb) from [<bfa26a87>] (line6_unlink_audio_urbs+0x6a/0x6c [snd_usb_line6]) |
| [<bfa26a87>] (line6_unlink_audio_urbs [snd_usb_line6]) from [<bfa26acb>] (line6_stream_stop+0x42/0x5c [snd_usb_line6]) |
| [<bfa26acb>] (line6_stream_stop [snd_usb_line6]) from [<bfa26fe7>] (snd_line6_trigger+0xb6/0xf4 [snd_usb_line6]) |
| [<bfa26fe7>] (snd_line6_trigger [snd_usb_line6]) from [<bf8d47b7>] (snd_pcm_do_stop+0x36/0x38 [snd_pcm]) |
| [<bf8d47b7>] (snd_pcm_do_stop [snd_pcm]) from [<bf8d462f>] (snd_pcm_action_single+0x22/0x40 [snd_pcm]) |
| [<bf8d462f>] (snd_pcm_action_single [snd_pcm]) from [<bf8d46f9>] (snd_pcm_action+0xac/0xb0 [snd_pcm]) |
| [<bf8d46f9>] (snd_pcm_action [snd_pcm]) from [<bf8d4b61>] (snd_pcm_drop+0x38/0x64 [snd_pcm]) |
| [<bf8d4b61>] (snd_pcm_drop [snd_pcm]) from [<bf8d6233>] (snd_pcm_common_ioctl1+0x7fe/0xbe8 [snd_pcm]) |
| [<bf8d6233>] (snd_pcm_common_ioctl1 [snd_pcm]) from [<bf8d6779>] (snd_pcm_playback_ioctl1+0x15c/0x51c [snd_pcm]) |
| [<bf8d6779>] (snd_pcm_playback_ioctl1 [snd_pcm]) from [<bf8d6b59>] (snd_pcm_playback_ioctl+0x20/0x28 [snd_pcm]) |
| [<bf8d6b59>] (snd_pcm_playback_ioctl [snd_pcm]) from [<c016714b>] (do_vfs_ioctl+0x3af/0x5c8) |
| |
| Fixes: 63e20df1e5b2 ('ALSA: line6: Reorganize PCM stream handling') |
| Reviewed-by: Stefan Hajnoczi <stefanha@gmail.com> |
| Signed-off-by: Andrej Krutak <dev@andree.sk> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| sound/usb/line6/pcm.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| --- a/sound/usb/line6/pcm.c |
| +++ b/sound/usb/line6/pcm.c |
| @@ -210,7 +210,9 @@ static void line6_stream_stop(struct snd |
| spin_lock_irqsave(&pstr->lock, flags); |
| clear_bit(type, &pstr->running); |
| if (!pstr->running) { |
| + spin_unlock_irqrestore(&pstr->lock, flags); |
| line6_unlink_audio_urbs(line6pcm, pstr); |
| + spin_lock_irqsave(&pstr->lock, flags); |
| if (direction == SNDRV_PCM_STREAM_CAPTURE) { |
| line6pcm->prev_fbuf = NULL; |
| line6pcm->prev_fsize = 0; |