Skip to content

Commit 2ba1fe7

Browse files
committed
ALSA: hrtimer: Fix stall by hrtimer_cancel()
hrtimer_cancel() waits for the completion from the callback, thus it must not be called inside the callback itself. This was already a problem in the past with ALSA hrtimer driver, and the early commit [fcfdebe: ALSA: hrtimer - Fix lock-up] tried to address it. However, the previous fix is still insufficient: it may still cause a lockup when the ALSA timer instance reprograms itself in its callback. Then it invokes the start function even in snd_timer_interrupt() that is called in hrtimer callback itself, results in a CPU stall. This is no hypothetical problem but actually triggered by syzkaller fuzzer. This patch tries to fix the issue again. Now we call hrtimer_try_to_cancel() at both start and stop functions so that it won't fall into a deadlock, yet giving some chance to cancel the queue if the functions have been called outside the callback. The proper hrtimer_cancel() is called in anyway at closing, so this should be enough. Reported-and-tested-by: Dmitry Vyukov <dvyukov@google.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent db8948e commit 2ba1fe7

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

Diff for: sound/core/hrtimer.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_timer *t)
9090
struct snd_hrtimer *stime = t->private_data;
9191

9292
atomic_set(&stime->running, 0);
93-
hrtimer_cancel(&stime->hrt);
93+
hrtimer_try_to_cancel(&stime->hrt);
9494
hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
9595
HRTIMER_MODE_REL);
9696
atomic_set(&stime->running, 1);
@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
101101
{
102102
struct snd_hrtimer *stime = t->private_data;
103103
atomic_set(&stime->running, 0);
104+
hrtimer_try_to_cancel(&stime->hrt);
104105
return 0;
105106
}
106107

0 commit comments

Comments
 (0)