summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch51
1 files changed, 51 insertions, 0 deletions
diff --git a/debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch b/debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch
new file mode 100644
index 000000000..d93342369
--- /dev/null
+++ b/debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch
@@ -0,0 +1,51 @@
+From baa58a4f1714630ef1a780575a907b4f80344e19 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Thu, 6 Dec 2018 10:15:13 +0100
+Subject: [PATCH 103/347] hrtimer: move state change before hrtimer_cancel in
+ do_nanosleep()
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz
+
+There is a small window between setting t->task to NULL and waking the
+task up (which would set TASK_RUNNING). So the timer would fire, run and
+set ->task to NULL while the other side/do_nanosleep() wouldn't enter
+freezable_schedule(). After all we are peemptible here (in
+do_nanosleep() and on the timer wake up path) and on KVM/virt the
+virt-CPU might get preempted.
+So do_nanosleep() wouldn't enter freezable_schedule() but cancel the
+timer which is still running and wait for it via
+hrtimer_wait_for_timer(). Then wait_event()/might_sleep() would complain
+that it is invoked with state != TASK_RUNNING.
+This isn't a problem since it would be reset to TASK_RUNNING later
+anyway and we don't rely on the previous state.
+
+Move the state update to TASK_RUNNING before hrtimer_cancel() so there
+are no complains from might_sleep() about wrong state.
+
+Cc: stable-rt@vger.kernel.org
+Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/time/hrtimer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 0833e5cf224d..009001f06d33 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -1852,12 +1852,12 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
+ if (likely(t->task))
+ freezable_schedule();
+
++ __set_current_state(TASK_RUNNING);
+ hrtimer_cancel(&t->timer);
+ mode = HRTIMER_MODE_ABS;
+
+ } while (t->task && !signal_pending(current));
+
+- __set_current_state(TASK_RUNNING);
+
+ if (!t->task)
+ return 0;
+--
+2.36.1
+