Skip to content

Commit

Permalink
sound: oss: vwsnd: avoid interruptible_sleep_on
Browse files Browse the repository at this point in the history
Interruptible_sleep_on is racy and we want to remove it. This replaces
the use in the vwsnd driver with an open-coded prepare_to_wait
loop that fixes the race between concurrent open() and close() calls,
and also drops the global mutex while waiting here, which restores
the original behavior that was changed during the BKL removal.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Arnd Bergmann authored and Takashi Iwai committed Jan 14, 2014
1 parent 1a21576 commit 7bd6972
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions sound/oss/vwsnd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
vwsnd_dev_t *devc;
int minor = iminor(inode);
int sw_samplefmt;
DEFINE_WAIT(wait);

DBGE("(inode=0x%p, file=0x%p)\n", inode, file);

Expand All @@ -2937,21 +2938,26 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
}

mutex_lock(&devc->open_mutex);
while (devc->open_mode & file->f_mode) {
while (1) {
prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE);
if (!(devc->open_mode & file->f_mode))
break;

mutex_unlock(&devc->open_mutex);
mutex_unlock(&vwsnd_mutex);
if (file->f_flags & O_NONBLOCK) {
DEC_USE_COUNT;
mutex_unlock(&vwsnd_mutex);
return -EBUSY;
}
interruptible_sleep_on(&devc->open_wait);
schedule();
if (signal_pending(current)) {
DEC_USE_COUNT;
mutex_unlock(&vwsnd_mutex);
return -ERESTARTSYS;
}
mutex_lock(&vwsnd_mutex);
mutex_lock(&devc->open_mutex);
}
finish_wait(&devc->open_wait, &wait);
devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
mutex_unlock(&devc->open_mutex);

Expand Down

0 comments on commit 7bd6972

Please sign in to comment.