summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0184-hrtimer-cpu_chill-save-task-state-in-saved_state.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0184-hrtimer-cpu_chill-save-task-state-in-saved_state.patch')
-rw-r--r--debian/patches-rt/0184-hrtimer-cpu_chill-save-task-state-in-saved_state.patch63
1 files changed, 63 insertions, 0 deletions
diff --git a/debian/patches-rt/0184-hrtimer-cpu_chill-save-task-state-in-saved_state.patch b/debian/patches-rt/0184-hrtimer-cpu_chill-save-task-state-in-saved_state.patch
new file mode 100644
index 000000000..6917a5783
--- /dev/null
+++ b/debian/patches-rt/0184-hrtimer-cpu_chill-save-task-state-in-saved_state.patch
@@ -0,0 +1,63 @@
+From 351c688963d6bfafec5cf05168e195effc77811c Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 26 Feb 2019 12:31:10 +0100
+Subject: [PATCH 184/347] hrtimer: cpu_chill(): save task state in
+ ->saved_state()
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz
+
+In the previous change I saved the current task state on stack. This was
+bad because while the task is scheduled-out it might receive a wake-up.
+The wake up changes the task state and we must not destroy it.
+
+Save the task-state in ->saved_state under a PI-lock to unsure that
+state changes during are not missed while the task temporary scheduled
+out.
+
+Reported-by: Mike Galbraith <efault@gmx.de>
+Tested-by: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/time/hrtimer.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 96e505abf939..aa8f3177580a 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -1967,20 +1967,28 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
+ */
+ void cpu_chill(void)
+ {
+- ktime_t chill_time;
+ unsigned int freeze_flag = current->flags & PF_NOFREEZE;
+- long saved_state;
++ struct task_struct *self = current;
++ ktime_t chill_time;
+
+- saved_state = current->state;
+- chill_time = ktime_set(0, NSEC_PER_MSEC);
++ raw_spin_lock_irq(&self->pi_lock);
++ self->saved_state = self->state;
+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE);
++ raw_spin_unlock_irq(&self->pi_lock);
++
++ chill_time = ktime_set(0, NSEC_PER_MSEC);
++
+ current->flags |= PF_NOFREEZE;
+ sleeping_lock_inc();
+ schedule_hrtimeout(&chill_time, HRTIMER_MODE_REL_HARD);
+ sleeping_lock_dec();
+ if (!freeze_flag)
+ current->flags &= ~PF_NOFREEZE;
+- __set_current_state_no_track(saved_state);
++
++ raw_spin_lock_irq(&self->pi_lock);
++ __set_current_state_no_track(self->saved_state);
++ self->saved_state = TASK_RUNNING;
++ raw_spin_unlock_irq(&self->pi_lock);
+ }
+ EXPORT_SYMBOL(cpu_chill);
+ #endif
+--
+2.36.1
+