aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/hrtimer.c')
-rw-r--r--kernel/time/hrtimer.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 5af758473488..bdcbf3036a40 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1468,6 +1468,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
base += hrtimer_clockid_to_base(clock_id);
timer->is_soft = softtimer;
timer->is_hard = !!(mode & HRTIMER_MODE_HARD);
+ timer->is_chill = !!(mode & HRTIMER_MODE_CHILL);
timer->base = &cpu_base->clock_base[base];
timerqueue_init(&timer->node);
}
@@ -1834,7 +1835,7 @@ static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer)
t->task = NULL;
if (task)
- wake_up_process(task);
+ wake_up_state(task, timer->is_chill ? TASK_RTLOCK_WAIT : TASK_NORMAL);
return HRTIMER_NORESTART;
}
@@ -2052,6 +2053,34 @@ SYSCALL_DEFINE2(nanosleep_time32, struct old_timespec32 __user *, rqtp,
}
#endif
+#ifdef CONFIG_PREEMPT_RT
+/*
+ * Sleep for 1 ms in hope whoever holds what we want will let it go.
+ */
+void cpu_chill(void)
+{
+ unsigned int freeze_flag = current->flags & PF_NOFREEZE;
+ ktime_t chill_time;
+
+ local_irq_disable();
+ current_save_and_set_rtlock_wait_state();
+ local_irq_enable();
+
+ chill_time = ktime_set(0, NSEC_PER_MSEC);
+
+ current->flags |= PF_NOFREEZE;
+ schedule_hrtimeout(&chill_time,
+ HRTIMER_MODE_REL_HARD| HRTIMER_MODE_CHILL);
+ if (!freeze_flag)
+ current->flags &= ~PF_NOFREEZE;
+
+ local_irq_disable();
+ current_restore_rtlock_saved_state();
+ local_irq_enable();
+}
+EXPORT_SYMBOL(cpu_chill);
+#endif
+
/*
* Functions related to boot-time initialization:
*/