summaryrefslogtreecommitdiffstats
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.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 5d4a0342f934..678349aec483 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -528,14 +528,11 @@ static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)
528 sched_clock_idle_wakeup_event(); 528 sched_clock_idle_wakeup_event();
529} 529}
530 530
531static ktime_t tick_nohz_start_idle(struct tick_sched *ts) 531static void tick_nohz_start_idle(struct tick_sched *ts)
532{ 532{
533 ktime_t now = ktime_get(); 533 ts->idle_entrytime = ktime_get();
534
535 ts->idle_entrytime = now;
536 ts->idle_active = 1; 534 ts->idle_active = 1;
537 sched_clock_idle_sleep_event(); 535 sched_clock_idle_sleep_event();
538 return now;
539} 536}
540 537
541/** 538/**
@@ -894,19 +891,21 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
894 return true; 891 return true;
895} 892}
896 893
897static void __tick_nohz_idle_enter(struct tick_sched *ts) 894static void __tick_nohz_idle_stop_tick(struct tick_sched *ts)
898{ 895{
899 ktime_t now, expires; 896 ktime_t expires;
900 int cpu = smp_processor_id(); 897 int cpu = smp_processor_id();
901 898
902 now = tick_nohz_start_idle(ts);
903
904 if (can_stop_idle_tick(cpu, ts)) { 899 if (can_stop_idle_tick(cpu, ts)) {
905 int was_stopped = ts->tick_stopped; 900 int was_stopped = ts->tick_stopped;
906 901
907 ts->idle_calls++; 902 ts->idle_calls++;
908 903
909 expires = tick_nohz_stop_sched_tick(ts, now, cpu); 904 /*
905 * The idle entry time should be a sufficient approximation of
906 * the current time at this point.
907 */
908 expires = tick_nohz_stop_sched_tick(ts, ts->idle_entrytime, cpu);
910 if (expires > 0LL) { 909 if (expires > 0LL) {
911 ts->idle_sleeps++; 910 ts->idle_sleeps++;
912 ts->idle_expires = expires; 911 ts->idle_expires = expires;
@@ -920,16 +919,19 @@ static void __tick_nohz_idle_enter(struct tick_sched *ts)
920} 919}
921 920
922/** 921/**
923 * tick_nohz_idle_enter - stop the idle tick from the idle task 922 * tick_nohz_idle_stop_tick - stop the idle tick from the idle task
924 * 923 *
925 * When the next event is more than a tick into the future, stop the idle tick 924 * When the next event is more than a tick into the future, stop the idle tick
926 * Called when we start the idle loop. 925 */
927 * 926void tick_nohz_idle_stop_tick(void)
928 * The arch is responsible of calling: 927{
928 __tick_nohz_idle_stop_tick(this_cpu_ptr(&tick_cpu_sched));
929}
930
931/**
932 * tick_nohz_idle_enter - prepare for entering idle on the current CPU
929 * 933 *
930 * - rcu_idle_enter() after its last use of RCU before the CPU is put 934 * Called when we start the idle loop.
931 * to sleep.
932 * - rcu_idle_exit() before the first use of RCU after the CPU is woken up.
933 */ 935 */
934void tick_nohz_idle_enter(void) 936void tick_nohz_idle_enter(void)
935{ 937{
@@ -941,7 +943,7 @@ void tick_nohz_idle_enter(void)
941 943
942 ts = this_cpu_ptr(&tick_cpu_sched); 944 ts = this_cpu_ptr(&tick_cpu_sched);
943 ts->inidle = 1; 945 ts->inidle = 1;
944 __tick_nohz_idle_enter(ts); 946 tick_nohz_start_idle(ts);
945 947
946 local_irq_enable(); 948 local_irq_enable();
947} 949}
@@ -958,10 +960,12 @@ void tick_nohz_irq_exit(void)
958{ 960{
959 struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched); 961 struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
960 962
961 if (ts->inidle) 963 if (ts->inidle) {
962 __tick_nohz_idle_enter(ts); 964 tick_nohz_start_idle(ts);
963 else 965 __tick_nohz_idle_stop_tick(ts);
966 } else {
964 tick_nohz_full_update_tick(ts); 967 tick_nohz_full_update_tick(ts);
968 }
965} 969}
966 970
967/** 971/**