aboutsummaryrefslogtreecommitdiff
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2014-04-02 12:10:53 +0530
committerAnders Roxell <anders.roxell@linaro.org>2014-09-29 11:11:29 +0200
commit260c0d8430535ddee870e8af6a0ac32000f347aa (patch)
tree16b9659807057ccb899fcf85fc9c96a9b92bc9d5 /kernel/hrtimer.c
parentc7ce4156b3f3c6e1ae1838c671372e57305fbce1 (diff)
hrtimer: update timer->state with 'pinned' information
'Pinned' information would be required in migrate_hrtimers() now, as we can migrate non-pinned timers away without a hotplug (i.e. with cpuset.quiesce). And so we may need to identify pinned timers now, as we can't migrate them. This patch reuses the timer->state variable for setting this flag as there were enough number of free bits available in this variable. And there is no point increasing size of this struct by adding another field. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index e0501fe7140d..3570a1393c9e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -941,7 +941,11 @@ static void __remove_hrtimer(struct hrtimer *timer,
if (!timerqueue_getnext(&base->active))
base->cpu_base->active_bases &= ~(1 << base->index);
out:
- timer->state = newstate;
+ /*
+ * We need to preserve PINNED state here, otherwise we may end up
+ * migrating pinned hrtimers as well.
+ */
+ timer->state = newstate | (timer->state & HRTIMER_STATE_PINNED);
}
/*
@@ -1011,6 +1015,10 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
timer_stats_hrtimer_set_start_info(timer);
+ /* Update pinned state */
+ timer->state &= ~HRTIMER_STATE_PINNED;
+ timer->state |= !!(mode & HRTIMER_MODE_PINNED) << HRTIMER_PINNED_SHIFT;
+
leftmost = enqueue_hrtimer(timer, new_base);
/*
@@ -1274,7 +1282,7 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
* hrtimer_start_range_ns() or in hrtimer_interrupt()
*/
if (restart != HRTIMER_NORESTART) {
- BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
+ BUG_ON(!(timer->state & HRTIMER_STATE_CALLBACK));
enqueue_hrtimer(timer, base);
}