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 --- sound/core/timer.c | 4 ++++ 1 file changed, 4 insertions(+)
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, ¶ms, 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; }