From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
alsa-devel@alsa-project.org, broonie@kernel.org, tiwai@suse.com
Subject: Re: [BUG] ALSA: core: possible deadlock involving waiting and locking operations
Date: Sat, 29 Jan 2022 13:27:22 +0900 [thread overview]
Message-ID: <YfTCKrjpaeKWFglO@workstation> (raw)
In-Reply-To: <56766037-972e-9e5b-74c1-88633a72a77f@gmail.com>
Hi,
On Sat, Jan 29, 2022 at 11:33:26AM +0800, Jia-Ju Bai wrote:
> Hello,
>
> My static analysis tool reports a possible deadlock in the sound driver
> in Linux 5.10:
>
> snd_card_disconnect_sync()
> spin_lock_irq(&card->files_lock); --> Line 461 (Lock A)
> wait_event_lock_irq(card->remove_sleep, ...); --> Line 462 (Wait X)
> spin_unlock_irq(&card->files_lock); --> Line 465 (Unlock A)
>
> snd_hwdep_release()
> mutex_lock(&hw->open_mutex); --> Line 152 (Lock B)
> mutex_unlock(&hw->open_mutex); --> Line 157 (Unlock B)
> snd_card_file_remove()
> wake_up_all(&card->remove_sleep); --> Line 976 (Wake X)
>
> snd_hwdep_open()
> mutex_lock(&hw->open_mutex); --> Line 95 (Lock B)
> snd_card_file_add()
> spin_lock(&card->files_lock); --> Line 932 (Lock A)
> spin_unlock(&card->files_lock); --> Line 940 (Unlock A)
> mutex_unlock(&hw->open_mutex); --> Line 139 (Unlock B)
>
> When snd_card_disconnect_sync() is executed, "Wait X" is performed by
> holding "Lock A". If snd_hwdep_open() is executed at this time, it holds
> "Lock B" and then waits for acquiring "Lock A". If snd_hwdep_release()
> is executed at this time, it waits for acquiring "Lock B", and thus
> "Wake X" cannot be performed to wake up "Wait X" in
> snd_card_disconnect_sync(), causing a possible deadlock.
>
> I am not quite sure whether this possible problem is real and how to fix
> it if it is real.
> Any feedback would be appreciated, thanks :)
I'm interested in your report about the deadlock, and seek the cause
of issue. Then I realized that we should take care of the replacement of
file_operation before acquiring spinlock in snd_card_disconnect_sync().
```
snd_card_disconnect_sync()
->snd_card_disconnect()
->spin_lock()
->list_for_each_entry()
mfile->file->f_op = snd_shutdown_f_ops
->spin_unlock()
->spin_lock_irq()
->wait_event_lock_irq()
->spin_unlock_irq()
```
The implementation of snd_shutdown_f_ops has no value for .open, therefore
snd_hwdep_open() is not called anymore when waiting the event. The mutex
(Lock B) is not acquired in process context of ALSA hwdep application.
The original .release function can be called by snd_disconnect_release()
via replaced snd_shutdown_f_ops. In the case, as you can see, the spinlock
(Lock A) is not acquired.
I think there are no race conditions against Lock A and B in process
context of ALSA hwdep application after card disconnection. But it would
be probable to overlook the other case. I would be glad to receive your
check for the above procedure.
Thanks
Takashi Sakamoto
WARNING: multiple messages have this Message-ID (diff)
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: perex@perex.cz, tiwai@suse.com, broonie@kernel.org,
alsa-devel@alsa-project.org,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [BUG] ALSA: core: possible deadlock involving waiting and locking operations
Date: Sat, 29 Jan 2022 13:27:22 +0900 [thread overview]
Message-ID: <YfTCKrjpaeKWFglO@workstation> (raw)
In-Reply-To: <56766037-972e-9e5b-74c1-88633a72a77f@gmail.com>
Hi,
On Sat, Jan 29, 2022 at 11:33:26AM +0800, Jia-Ju Bai wrote:
> Hello,
>
> My static analysis tool reports a possible deadlock in the sound driver
> in Linux 5.10:
>
> snd_card_disconnect_sync()
> spin_lock_irq(&card->files_lock); --> Line 461 (Lock A)
> wait_event_lock_irq(card->remove_sleep, ...); --> Line 462 (Wait X)
> spin_unlock_irq(&card->files_lock); --> Line 465 (Unlock A)
>
> snd_hwdep_release()
> mutex_lock(&hw->open_mutex); --> Line 152 (Lock B)
> mutex_unlock(&hw->open_mutex); --> Line 157 (Unlock B)
> snd_card_file_remove()
> wake_up_all(&card->remove_sleep); --> Line 976 (Wake X)
>
> snd_hwdep_open()
> mutex_lock(&hw->open_mutex); --> Line 95 (Lock B)
> snd_card_file_add()
> spin_lock(&card->files_lock); --> Line 932 (Lock A)
> spin_unlock(&card->files_lock); --> Line 940 (Unlock A)
> mutex_unlock(&hw->open_mutex); --> Line 139 (Unlock B)
>
> When snd_card_disconnect_sync() is executed, "Wait X" is performed by
> holding "Lock A". If snd_hwdep_open() is executed at this time, it holds
> "Lock B" and then waits for acquiring "Lock A". If snd_hwdep_release()
> is executed at this time, it waits for acquiring "Lock B", and thus
> "Wake X" cannot be performed to wake up "Wait X" in
> snd_card_disconnect_sync(), causing a possible deadlock.
>
> I am not quite sure whether this possible problem is real and how to fix
> it if it is real.
> Any feedback would be appreciated, thanks :)
I'm interested in your report about the deadlock, and seek the cause
of issue. Then I realized that we should take care of the replacement of
file_operation before acquiring spinlock in snd_card_disconnect_sync().
```
snd_card_disconnect_sync()
->snd_card_disconnect()
->spin_lock()
->list_for_each_entry()
mfile->file->f_op = snd_shutdown_f_ops
->spin_unlock()
->spin_lock_irq()
->wait_event_lock_irq()
->spin_unlock_irq()
```
The implementation of snd_shutdown_f_ops has no value for .open, therefore
snd_hwdep_open() is not called anymore when waiting the event. The mutex
(Lock B) is not acquired in process context of ALSA hwdep application.
The original .release function can be called by snd_disconnect_release()
via replaced snd_shutdown_f_ops. In the case, as you can see, the spinlock
(Lock A) is not acquired.
I think there are no race conditions against Lock A and B in process
context of ALSA hwdep application after card disconnection. But it would
be probable to overlook the other case. I would be glad to receive your
check for the above procedure.
Thanks
Takashi Sakamoto
next prev parent reply other threads:[~2022-01-29 4:28 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-29 3:33 [BUG] ALSA: core: possible deadlock involving waiting and locking operations Jia-Ju Bai
2022-01-29 4:27 ` Takashi Sakamoto [this message]
2022-01-29 4:27 ` Takashi Sakamoto
2022-01-29 8:07 ` Jia-Ju Bai
2022-01-29 8:20 ` Takashi Iwai
2022-01-29 8:20 ` Takashi Iwai
2022-01-29 8:28 ` Jia-Ju Bai
2022-01-29 8:28 ` Jia-Ju Bai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YfTCKrjpaeKWFglO@workstation \
--to=o-takashi@sakamocchi.jp \
--cc=alsa-devel@alsa-project.org \
--cc=baijiaju1990@gmail.com \
--cc=broonie@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.