summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-06-02 17:35:30 +0200
committerTakashi Iwai <tiwai@suse.de>2017-06-07 10:25:53 +0200
commitd7f910bfedd863d13ea320030fe98e42d0938ed5 (patch)
tree51ec98386371c6adead80f99ee88a42ccb6dbb19
parentALSA: timer: Improve user queue reallocation (diff)
downloadlinux-d7f910bfedd863d13ea320030fe98e42d0938ed5.tar.xz
linux-d7f910bfedd863d13ea320030fe98e42d0938ed5.zip
ALSA: timer: Wrap with spinlock for queue access
For accessing the snd_timer_user queue indices, we take tu->qlock. But it's forgotten in a couple of places. The one in snd_timer_user_params() should be safe without the spinlock as the timer is already stopped. But it's better for consistency. The one in poll is just a read-out, so it's not inevitably needed, but it'd be good to make the result consistent, too. Tested-by: Alexander Potapenko <glider@google.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/core/timer.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 96cffb1be57f..148290ace756 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1755,6 +1755,7 @@ static int snd_timer_user_params(struct file *file,
if (err < 0)
goto _end;
}
+ spin_lock_irq(&tu->qlock);
tu->qhead = tu->qtail = tu->qused = 0;
if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
if (tu->tread) {
@@ -1775,6 +1776,7 @@ static int snd_timer_user_params(struct file *file,
}
tu->filter = params.filter;
tu->ticks = params.ticks;
+ spin_unlock_irq(&tu->qlock);
err = 0;
_end:
if (copy_to_user(_params, &params, sizeof(params)))
@@ -2022,10 +2024,12 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
poll_wait(file, &tu->qchange_sleep, wait);
mask = 0;
+ spin_lock_irq(&tu->qlock);
if (tu->qused)
mask |= POLLIN | POLLRDNORM;
if (tu->disconnected)
mask |= POLLERR;
+ spin_unlock_irq(&tu->qlock);
return mask;
}