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.c164
1 files changed, 108 insertions, 56 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4d219398167..8f3fc2582d38 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -155,7 +155,7 @@ void tick_nohz_update_jiffies(void)
155 touch_softlockup_watchdog(); 155 touch_softlockup_watchdog();
156} 156}
157 157
158void tick_nohz_stop_idle(int cpu) 158static void tick_nohz_stop_idle(int cpu)
159{ 159{
160 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 160 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
161 161
@@ -247,7 +247,7 @@ void tick_nohz_stop_sched_tick(int inidle)
247 if (need_resched()) 247 if (need_resched())
248 goto end; 248 goto end;
249 249
250 if (unlikely(local_softirq_pending())) { 250 if (unlikely(local_softirq_pending() && cpu_online(cpu))) {
251 static int ratelimit; 251 static int ratelimit;
252 252
253 if (ratelimit < 10) { 253 if (ratelimit < 10) {
@@ -270,7 +270,7 @@ void tick_nohz_stop_sched_tick(int inidle)
270 next_jiffies = get_next_timer_interrupt(last_jiffies); 270 next_jiffies = get_next_timer_interrupt(last_jiffies);
271 delta_jiffies = next_jiffies - last_jiffies; 271 delta_jiffies = next_jiffies - last_jiffies;
272 272
273 if (rcu_needs_cpu(cpu)) 273 if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu))
274 delta_jiffies = 1; 274 delta_jiffies = 1;
275 /* 275 /*
276 * Do not stop the tick, if we are only one off 276 * Do not stop the tick, if we are only one off
@@ -282,8 +282,31 @@ void tick_nohz_stop_sched_tick(int inidle)
282 /* Schedule the tick, if we are at least one jiffie off */ 282 /* Schedule the tick, if we are at least one jiffie off */
283 if ((long)delta_jiffies >= 1) { 283 if ((long)delta_jiffies >= 1) {
284 284
285 /*
286 * calculate the expiry time for the next timer wheel
287 * timer
288 */
289 expires = ktime_add_ns(last_update, tick_period.tv64 *
290 delta_jiffies);
291
292 /*
293 * If this cpu is the one which updates jiffies, then
294 * give up the assignment and let it be taken by the
295 * cpu which runs the tick timer next, which might be
296 * this cpu as well. If we don't drop this here the
297 * jiffies might be stale and do_timer() never
298 * invoked.
299 */
300 if (cpu == tick_do_timer_cpu)
301 tick_do_timer_cpu = TICK_DO_TIMER_NONE;
302
285 if (delta_jiffies > 1) 303 if (delta_jiffies > 1)
286 cpu_set(cpu, nohz_cpu_mask); 304 cpu_set(cpu, nohz_cpu_mask);
305
306 /* Skip reprogram of event if its not changed */
307 if (ts->tick_stopped && ktime_equal(expires, dev->next_event))
308 goto out;
309
287 /* 310 /*
288 * nohz_stop_sched_tick can be called several times before 311 * nohz_stop_sched_tick can be called several times before
289 * the nohz_restart_sched_tick is called. This happens when 312 * the nohz_restart_sched_tick is called. This happens when
@@ -300,23 +323,12 @@ void tick_nohz_stop_sched_tick(int inidle)
300 goto out; 323 goto out;
301 } 324 }
302 325
303 ts->idle_tick = ts->sched_timer.expires; 326 ts->idle_tick = hrtimer_get_expires(&ts->sched_timer);
304 ts->tick_stopped = 1; 327 ts->tick_stopped = 1;
305 ts->idle_jiffies = last_jiffies; 328 ts->idle_jiffies = last_jiffies;
306 rcu_enter_nohz(); 329 rcu_enter_nohz();
307 } 330 }
308 331
309 /*
310 * If this cpu is the one which updates jiffies, then
311 * give up the assignment and let it be taken by the
312 * cpu which runs the tick timer next, which might be
313 * this cpu as well. If we don't drop this here the
314 * jiffies might be stale and do_timer() never
315 * invoked.
316 */
317 if (cpu == tick_do_timer_cpu)
318 tick_do_timer_cpu = TICK_DO_TIMER_NONE;
319
320 ts->idle_sleeps++; 332 ts->idle_sleeps++;
321 333
322 /* 334 /*
@@ -332,12 +344,7 @@ void tick_nohz_stop_sched_tick(int inidle)
332 goto out; 344 goto out;
333 } 345 }
334 346
335 /* 347 /* Mark expiries */
336 * calculate the expiry time for the next timer wheel
337 * timer
338 */
339 expires = ktime_add_ns(last_update, tick_period.tv64 *
340 delta_jiffies);
341 ts->idle_expires = expires; 348 ts->idle_expires = expires;
342 349
343 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { 350 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
@@ -377,6 +384,32 @@ ktime_t tick_nohz_get_sleep_length(void)
377 return ts->sleep_length; 384 return ts->sleep_length;
378} 385}
379 386
387static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
388{
389 hrtimer_cancel(&ts->sched_timer);
390 hrtimer_set_expires(&ts->sched_timer, ts->idle_tick);
391
392 while (1) {
393 /* Forward the time to expire in the future */
394 hrtimer_forward(&ts->sched_timer, now, tick_period);
395
396 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
397 hrtimer_start_expires(&ts->sched_timer,
398 HRTIMER_MODE_ABS);
399 /* Check, if the timer was already in the past */
400 if (hrtimer_active(&ts->sched_timer))
401 break;
402 } else {
403 if (!tick_program_event(
404 hrtimer_get_expires(&ts->sched_timer), 0))
405 break;
406 }
407 /* Update jiffies and reread time */
408 tick_do_update_jiffies64(now);
409 now = ktime_get();
410 }
411}
412
380/** 413/**
381 * tick_nohz_restart_sched_tick - restart the idle tick from the idle task 414 * tick_nohz_restart_sched_tick - restart the idle tick from the idle task
382 * 415 *
@@ -430,35 +463,16 @@ void tick_nohz_restart_sched_tick(void)
430 */ 463 */
431 ts->tick_stopped = 0; 464 ts->tick_stopped = 0;
432 ts->idle_exittime = now; 465 ts->idle_exittime = now;
433 hrtimer_cancel(&ts->sched_timer);
434 ts->sched_timer.expires = ts->idle_tick;
435 466
436 while (1) { 467 tick_nohz_restart(ts, now);
437 /* Forward the time to expire in the future */
438 hrtimer_forward(&ts->sched_timer, now, tick_period);
439 468
440 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
441 hrtimer_start(&ts->sched_timer,
442 ts->sched_timer.expires,
443 HRTIMER_MODE_ABS);
444 /* Check, if the timer was already in the past */
445 if (hrtimer_active(&ts->sched_timer))
446 break;
447 } else {
448 if (!tick_program_event(ts->sched_timer.expires, 0))
449 break;
450 }
451 /* Update jiffies and reread time */
452 tick_do_update_jiffies64(now);
453 now = ktime_get();
454 }
455 local_irq_enable(); 469 local_irq_enable();
456} 470}
457 471
458static int tick_nohz_reprogram(struct tick_sched *ts, ktime_t now) 472static int tick_nohz_reprogram(struct tick_sched *ts, ktime_t now)
459{ 473{
460 hrtimer_forward(&ts->sched_timer, now, tick_period); 474 hrtimer_forward(&ts->sched_timer, now, tick_period);
461 return tick_program_event(ts->sched_timer.expires, 0); 475 return tick_program_event(hrtimer_get_expires(&ts->sched_timer), 0);
462} 476}
463 477
464/* 478/*
@@ -503,10 +517,6 @@ static void tick_nohz_handler(struct clock_event_device *dev)
503 update_process_times(user_mode(regs)); 517 update_process_times(user_mode(regs));
504 profile_tick(CPU_PROFILING); 518 profile_tick(CPU_PROFILING);
505 519
506 /* Do not restart, when we are in the idle loop */
507 if (ts->tick_stopped)
508 return;
509
510 while (tick_nohz_reprogram(ts, now)) { 520 while (tick_nohz_reprogram(ts, now)) {
511 now = ktime_get(); 521 now = ktime_get();
512 tick_do_update_jiffies64(now); 522 tick_do_update_jiffies64(now);
@@ -541,7 +551,7 @@ static void tick_nohz_switch_to_nohz(void)
541 next = tick_init_jiffy_update(); 551 next = tick_init_jiffy_update();
542 552
543 for (;;) { 553 for (;;) {
544 ts->sched_timer.expires = next; 554 hrtimer_set_expires(&ts->sched_timer, next);
545 if (!tick_program_event(next, 0)) 555 if (!tick_program_event(next, 0))
546 break; 556 break;
547 next = ktime_add(next, tick_period); 557 next = ktime_add(next, tick_period);
@@ -552,6 +562,41 @@ static void tick_nohz_switch_to_nohz(void)
552 smp_processor_id()); 562 smp_processor_id());
553} 563}
554 564
565/*
566 * When NOHZ is enabled and the tick is stopped, we need to kick the
567 * tick timer from irq_enter() so that the jiffies update is kept
568 * alive during long running softirqs. That's ugly as hell, but
569 * correctness is key even if we need to fix the offending softirq in
570 * the first place.
571 *
572 * Note, this is different to tick_nohz_restart. We just kick the
573 * timer and do not touch the other magic bits which need to be done
574 * when idle is left.
575 */
576static void tick_nohz_kick_tick(int cpu)
577{
578#if 0
579 /* Switch back to 2.6.27 behaviour */
580
581 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
582 ktime_t delta, now;
583
584 if (!ts->tick_stopped)
585 return;
586
587 /*
588 * Do not touch the tick device, when the next expiry is either
589 * already reached or less/equal than the tick period.
590 */
591 now = ktime_get();
592 delta = ktime_sub(hrtimer_get_expires(&ts->sched_timer), now);
593 if (delta.tv64 <= tick_period.tv64)
594 return;
595
596 tick_nohz_restart(ts, now);
597#endif
598}
599
555#else 600#else
556 601
557static inline void tick_nohz_switch_to_nohz(void) { } 602static inline void tick_nohz_switch_to_nohz(void) { }
@@ -559,6 +604,19 @@ static inline void tick_nohz_switch_to_nohz(void) { }
559#endif /* NO_HZ */ 604#endif /* NO_HZ */
560 605
561/* 606/*
607 * Called from irq_enter to notify about the possible interruption of idle()
608 */
609void tick_check_idle(int cpu)
610{
611 tick_check_oneshot_broadcast(cpu);
612#ifdef CONFIG_NO_HZ
613 tick_nohz_stop_idle(cpu);
614 tick_nohz_update_jiffies();
615 tick_nohz_kick_tick(cpu);
616#endif
617}
618
619/*
562 * High resolution timer specific code 620 * High resolution timer specific code
563 */ 621 */
564#ifdef CONFIG_HIGH_RES_TIMERS 622#ifdef CONFIG_HIGH_RES_TIMERS
@@ -611,10 +669,6 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
611 profile_tick(CPU_PROFILING); 669 profile_tick(CPU_PROFILING);
612 } 670 }
613 671
614 /* Do not restart, when we are in the idle loop */
615 if (ts->tick_stopped)
616 return HRTIMER_NORESTART;
617
618 hrtimer_forward(timer, now, tick_period); 672 hrtimer_forward(timer, now, tick_period);
619 673
620 return HRTIMER_RESTART; 674 return HRTIMER_RESTART;
@@ -634,19 +688,17 @@ void tick_setup_sched_timer(void)
634 */ 688 */
635 hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 689 hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
636 ts->sched_timer.function = tick_sched_timer; 690 ts->sched_timer.function = tick_sched_timer;
637 ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
638 691
639 /* Get the next period (per cpu) */ 692 /* Get the next period (per cpu) */
640 ts->sched_timer.expires = tick_init_jiffy_update(); 693 hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
641 offset = ktime_to_ns(tick_period) >> 1; 694 offset = ktime_to_ns(tick_period) >> 1;
642 do_div(offset, num_possible_cpus()); 695 do_div(offset, num_possible_cpus());
643 offset *= smp_processor_id(); 696 offset *= smp_processor_id();
644 ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); 697 hrtimer_add_expires_ns(&ts->sched_timer, offset);
645 698
646 for (;;) { 699 for (;;) {
647 hrtimer_forward(&ts->sched_timer, now, tick_period); 700 hrtimer_forward(&ts->sched_timer, now, tick_period);
648 hrtimer_start(&ts->sched_timer, ts->sched_timer.expires, 701 hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS);
649 HRTIMER_MODE_ABS);
650 /* Check, if the timer was already in the past */ 702 /* Check, if the timer was already in the past */
651 if (hrtimer_active(&ts->sched_timer)) 703 if (hrtimer_active(&ts->sched_timer))
652 break; 704 break;