aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r--kernel/time/tick-sched.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index d3f1ef4d5cbe..e0f59a21c061 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -222,6 +222,15 @@ void tick_nohz_stop_sched_tick(int inidle)
222 222
223 cpu = smp_processor_id(); 223 cpu = smp_processor_id();
224 ts = &per_cpu(tick_cpu_sched, cpu); 224 ts = &per_cpu(tick_cpu_sched, cpu);
225
226 /*
227 * Call to tick_nohz_start_idle stops the last_update_time from being
228 * updated. Thus, it must not be called in the event we are called from
229 * irq_exit() with the prior state different than idle.
230 */
231 if (!inidle && !ts->inidle)
232 goto end;
233
225 now = tick_nohz_start_idle(ts); 234 now = tick_nohz_start_idle(ts);
226 235
227 /* 236 /*
@@ -239,9 +248,6 @@ void tick_nohz_stop_sched_tick(int inidle)
239 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) 248 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
240 goto end; 249 goto end;
241 250
242 if (!inidle && !ts->inidle)
243 goto end;
244
245 ts->inidle = 1; 251 ts->inidle = 1;
246 252
247 if (need_resched()) 253 if (need_resched())
@@ -349,7 +355,7 @@ void tick_nohz_stop_sched_tick(int inidle)
349 355
350 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { 356 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
351 hrtimer_start(&ts->sched_timer, expires, 357 hrtimer_start(&ts->sched_timer, expires,
352 HRTIMER_MODE_ABS); 358 HRTIMER_MODE_ABS_PINNED);
353 /* Check, if the timer was already in the past */ 359 /* Check, if the timer was already in the past */
354 if (hrtimer_active(&ts->sched_timer)) 360 if (hrtimer_active(&ts->sched_timer))
355 goto out; 361 goto out;
@@ -395,7 +401,7 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
395 401
396 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { 402 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
397 hrtimer_start_expires(&ts->sched_timer, 403 hrtimer_start_expires(&ts->sched_timer,
398 HRTIMER_MODE_ABS); 404 HRTIMER_MODE_ABS_PINNED);
399 /* Check, if the timer was already in the past */ 405 /* Check, if the timer was already in the past */
400 if (hrtimer_active(&ts->sched_timer)) 406 if (hrtimer_active(&ts->sched_timer))
401 break; 407 break;
@@ -698,7 +704,8 @@ void tick_setup_sched_timer(void)
698 704
699 for (;;) { 705 for (;;) {
700 hrtimer_forward(&ts->sched_timer, now, tick_period); 706 hrtimer_forward(&ts->sched_timer, now, tick_period);
701 hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS); 707 hrtimer_start_expires(&ts->sched_timer,
708 HRTIMER_MODE_ABS_PINNED);
702 /* Check, if the timer was already in the past */ 709 /* Check, if the timer was already in the past */
703 if (hrtimer_active(&ts->sched_timer)) 710 if (hrtimer_active(&ts->sched_timer))
704 break; 711 break;