diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r-- | kernel/time/tick-sched.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 266c242dc354..c76aefe764b0 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -453,18 +453,22 @@ out: | |||
453 | * | 453 | * |
454 | * When the next event is more than a tick into the future, stop the idle tick | 454 | * When the next event is more than a tick into the future, stop the idle tick |
455 | * Called when we start the idle loop. | 455 | * Called when we start the idle loop. |
456 | * This also enters into RCU extended quiescent state so that this CPU doesn't | 456 | * |
457 | * need anymore to be part of any global grace period completion. This way | 457 | * If no use of RCU is made in the idle loop between |
458 | * the tick can be stopped safely as we don't need to report quiescent states. | 458 | * tick_nohz_idle_enter() and tick_nohz_idle_exit() calls, then |
459 | * tick_nohz_idle_enter_norcu() should be called instead and the arch | ||
460 | * doesn't need to call rcu_idle_enter() and rcu_idle_exit() explicitly. | ||
461 | * | ||
462 | * Otherwise the arch is responsible of calling: | ||
463 | * | ||
464 | * - rcu_idle_enter() after its last use of RCU before the CPU is put | ||
465 | * to sleep. | ||
466 | * - rcu_idle_exit() before the first use of RCU after the CPU is woken up. | ||
459 | */ | 467 | */ |
460 | void tick_nohz_idle_enter(void) | 468 | void __tick_nohz_idle_enter(void) |
461 | { | 469 | { |
462 | struct tick_sched *ts; | 470 | struct tick_sched *ts; |
463 | 471 | ||
464 | WARN_ON_ONCE(irqs_disabled()); | ||
465 | |||
466 | local_irq_disable(); | ||
467 | |||
468 | ts = &__get_cpu_var(tick_cpu_sched); | 472 | ts = &__get_cpu_var(tick_cpu_sched); |
469 | /* | 473 | /* |
470 | * set ts->inidle unconditionally. even if the system did not | 474 | * set ts->inidle unconditionally. even if the system did not |
@@ -473,9 +477,6 @@ void tick_nohz_idle_enter(void) | |||
473 | */ | 477 | */ |
474 | ts->inidle = 1; | 478 | ts->inidle = 1; |
475 | tick_nohz_stop_sched_tick(ts); | 479 | tick_nohz_stop_sched_tick(ts); |
476 | rcu_idle_enter(); | ||
477 | |||
478 | local_irq_enable(); | ||
479 | } | 480 | } |
480 | 481 | ||
481 | /** | 482 | /** |
@@ -551,7 +552,7 @@ void tick_nohz_idle_exit(void) | |||
551 | ktime_t now; | 552 | ktime_t now; |
552 | 553 | ||
553 | local_irq_disable(); | 554 | local_irq_disable(); |
554 | rcu_idle_exit(); | 555 | |
555 | if (ts->idle_active || (ts->inidle && ts->tick_stopped)) | 556 | if (ts->idle_active || (ts->inidle && ts->tick_stopped)) |
556 | now = ktime_get(); | 557 | now = ktime_get(); |
557 | 558 | ||