diff options
Diffstat (limited to 'debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch')
-rw-r--r-- | debian/patches-rt/0103-hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch | 51 |
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 + |