]> www.infradead.org Git - users/jedix/linux-maple.git/commit
ALSA: pcm: Fix rwsem deadlock for non-atomic PCM stream
authorTakashi Iwai <tiwai@suse.de>
Wed, 17 Feb 2016 13:30:26 +0000 (14:30 +0100)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 26 May 2016 22:45:10 +0000 (15:45 -0700)
commit142c6c63f2bad5d798727ac24978fcdbacc6d9d5
treeffcb1df43bdcea1ed24b2183a67e9f50ccc9b334
parenta072893017447993870a741dadf7f86c4865e646
ALSA: pcm: Fix rwsem deadlock for non-atomic PCM stream

Orabug: 23330868

[ Upstream commit 67ec1072b053c15564e6090ab30127895dc77a89 ]

A non-atomic PCM stream may take snd_pcm_link_rwsem rw semaphore twice
in the same code path, e.g. one in snd_pcm_action_nonatomic() and
another in snd_pcm_stream_lock().  Usually this is OK, but when a
write lock is issued between these two read locks, the problem
happens: the write lock is blocked due to the first reade lock, and
the second read lock is also blocked by the write lock.  This
eventually deadlocks.

The reason is the way rwsem manages waiters; it's queued like FIFO, so
even if the writer itself doesn't take the lock yet, it blocks all the
waiters (including reads) queued after it.

As a workaround, in this patch, we replace the standard down_write()
with an spinning loop.  This is far from optimal, but it's good
enough, as the spinning time is supposed to be relatively short for
normal PCM operations, and the code paths requiring the write lock
aren't called so often.

Reported-by: Vinod Koul <vinod.koul@intel.com>
Tested-by: Ramesh Babu <ramesh.babu@intel.com>
Cc: <stable@vger.kernel.org> # v3.18+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
(cherry picked from commit cab48a095169b3f981c600b4365170a076ac9f3a)

Signed-off-by: Dan Duval <dan.duval@oracle.com>
sound/core/pcm_native.c