Skip to content
  • Takashi Iwai's avatar
    ALSA: pcm: Fix rwsem deadlock for non-atomic PCM stream · 67ec1072
    Takashi Iwai authored
    
    
    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: default avatarVinod Koul <vinod.koul@intel.com>
    Tested-by: default avatarRamesh Babu <ramesh.babu@intel.com>
    Cc: <stable@vger.kernel.org> # v3.18+
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    67ec1072