diff mbox

[4.2.y-ckt,stable] Patch "ALSA: hrtimer: Fix stall by hrtimer_cancel()" has been added to the 4.2.y-ckt tree

Message ID 1453853566-20761-1-git-send-email-kamal@canonical.com
State New
Headers show

Commit Message

Kamal Mostafa Jan. 27, 2016, 12:12 a.m. UTC
This is a note to let you know that I have just added a patch titled

    ALSA: hrtimer: Fix stall by hrtimer_cancel()

to the linux-4.2.y-queue branch of the 4.2.y-ckt extended stable tree 
which can be found at:

    http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-4.2.y-queue

This patch is scheduled to be released in version 4.2.8-ckt3.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 4.2.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

---8<------------------------------------------------------------

From b753a870bbeaa50beb4c89d6181fd38956998270 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Mon, 18 Jan 2016 13:52:47 +0100
Subject: ALSA: hrtimer: Fix stall by hrtimer_cancel()

commit 2ba1fe7a06d3624f9a7586d672b55f08f7c670f3 upstream.

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
[fcfdebe70759: 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>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 sound/core/hrtimer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--
1.9.1
diff mbox

Patch

diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index f845ecf..656d9a9 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -90,7 +90,7 @@  static int snd_hrtimer_start(struct snd_timer *t)
 	struct snd_hrtimer *stime = t->private_data;

 	atomic_set(&stime->running, 0);
-	hrtimer_cancel(&stime->hrt);
+	hrtimer_try_to_cancel(&stime->hrt);
 	hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
 		      HRTIMER_MODE_REL);
 	atomic_set(&stime->running, 1);
@@ -101,6 +101,7 @@  static int snd_hrtimer_stop(struct snd_timer *t)
 {
 	struct snd_hrtimer *stime = t->private_data;
 	atomic_set(&stime->running, 0);
+	hrtimer_try_to_cancel(&stime->hrt);
 	return 0;
 }