OSDN Git Service

nohz: Avoid duplication of code related to got_idle_tick
[uclinux-h8/linux.git] / kernel / time / tick-sched.c
index c57c98c..956831c 100644 (file)
@@ -113,8 +113,7 @@ static ktime_t tick_init_jiffy_update(void)
        return period;
 }
 
-
-static void tick_sched_do_timer(ktime_t now)
+static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now)
 {
        int cpu = smp_processor_id();
 
@@ -134,6 +133,9 @@ static void tick_sched_do_timer(ktime_t now)
        /* Check, if the jiffies need an update */
        if (tick_do_timer_cpu == cpu)
                tick_do_update_jiffies64(now);
+
+       if (ts->inidle)
+               ts->got_idle_tick = 1;
 }
 
 static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
@@ -465,7 +467,9 @@ __setup("nohz=", setup_tick_nohz);
 
 bool tick_nohz_tick_stopped(void)
 {
-       return __this_cpu_read(tick_cpu_sched.tick_stopped);
+       struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
+
+       return ts->tick_stopped;
 }
 
 bool tick_nohz_tick_stopped_cpu(int cpu)
@@ -1014,8 +1018,8 @@ bool tick_nohz_idle_got_tick(void)
 {
        struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
 
-       if (ts->inidle > 1) {
-               ts->inidle = 1;
+       if (ts->got_idle_tick) {
+               ts->got_idle_tick = 0;
                return true;
        }
        return false;
@@ -1023,10 +1027,11 @@ bool tick_nohz_idle_got_tick(void)
 
 /**
  * tick_nohz_get_sleep_length - return the expected length of the current sleep
+ * @delta_next: duration until the next event if the tick cannot be stopped
  *
  * Called from power state control code with interrupts disabled
  */
-ktime_t tick_nohz_get_sleep_length(void)
+ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next)
 {
        struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
        struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
@@ -1040,12 +1045,14 @@ ktime_t tick_nohz_get_sleep_length(void)
 
        WARN_ON_ONCE(!ts->inidle);
 
+       *delta_next = ktime_sub(dev->next_event, now);
+
        if (!can_stop_idle_tick(cpu, ts))
-               goto out_dev;
+               return *delta_next;
 
        next_event = tick_nohz_next_event(ts, cpu);
        if (!next_event)
-               goto out_dev;
+               return *delta_next;
 
        /*
         * If the next highres timer to expire is earlier than next_event, the
@@ -1055,9 +1062,6 @@ ktime_t tick_nohz_get_sleep_length(void)
                           hrtimer_next_event_without(&ts->sched_timer));
 
        return ktime_sub(next_event, now);
-
-out_dev:
-       return ktime_sub(dev->next_event, now);
 }
 
 /**
@@ -1160,12 +1164,9 @@ static void tick_nohz_handler(struct clock_event_device *dev)
        struct pt_regs *regs = get_irq_regs();
        ktime_t now = ktime_get();
 
-       if (ts->inidle)
-               ts->inidle = 2;
-
        dev->next_event = KTIME_MAX;
 
-       tick_sched_do_timer(now);
+       tick_sched_do_timer(ts, now);
        tick_sched_handle(ts, regs);
 
        /* No need to reprogram if we are running tickless  */
@@ -1260,10 +1261,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
        struct pt_regs *regs = get_irq_regs();
        ktime_t now = ktime_get();
 
-       if (ts->inidle)
-               ts->inidle = 2;
-
-       tick_sched_do_timer(now);
+       tick_sched_do_timer(ts, now);
 
        /*
         * Do not call, when we are not in irq context and have