ALSA: pcm: oss: Unlock mutex temporarily for sleeping at read/write
ALSA PCM OSS layer calls the generic __snd_pcm_lib_xfer() helper for the actual transfer of the audio data. The xfer helper may sleep long for waiting for the enough space becoming empty for read/write, and it does unlock/relock for the substream lock. This works fine, so far, but a slight problem specific to OSS layer is that OSS layer wraps yet more mutex (runtime->oss.params_lock) over __snd_pcm_lib_xfer() call; so this mutex is still locked during a possible long sleep, and it prevents the whole ioctl and other actions applied to the given stream. This patch adds the temporarily unlock and relock of the mutex around __snd_pcm_lib_xfer() call in the OSS layer to be more friendly to the concurrent accesses. The long mutex protection itself shouldn't be a real issue for the normal systems, and its influence appears only on strange things like fuzzers. Link: https://lore.kernel.org/r/20200214171643.26212-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
e9a0ef0b5d
commit
146f66975b
@ -1217,8 +1217,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&runtime->oss.params_lock);
|
||||
ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
|
||||
frames, in_kernel);
|
||||
mutex_lock(&runtime->oss.params_lock);
|
||||
if (ret != -EPIPE && ret != -ESTRPIPE)
|
||||
break;
|
||||
/* test, if we can't store new data, because the stream */
|
||||
@ -1254,8 +1256,10 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
|
||||
ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
|
||||
if (ret < 0)
|
||||
break;
|
||||
mutex_unlock(&runtime->oss.params_lock);
|
||||
ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
|
||||
frames, in_kernel);
|
||||
mutex_lock(&runtime->oss.params_lock);
|
||||
if (ret == -EPIPE) {
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
|
||||
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user