*
  * @drv: the cpuidle driver
  * @dev: the cpuidle device
+ * @stop_tick: indication on whether or not to stop the tick
  *
  * Returns the index of the idle state.  The return value must not be negative.
+ *
+ * The memory location pointed to by @stop_tick is expected to be written the
+ * 'false' boolean value if the scheduler tick should not be stopped before
+ * entering the returned state.
  */
-int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
+int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+                  bool *stop_tick)
 {
-       return cpuidle_curr_governor->select(drv, dev);
+       return cpuidle_curr_governor->select(drv, dev, stop_tick);
 }
 
 /**
 
  * ladder_select_state - selects the next state to enter
  * @drv: cpuidle driver
  * @dev: the CPU
+ * @dummy: not used
  */
 static int ladder_select_state(struct cpuidle_driver *drv,
-                               struct cpuidle_device *dev)
+                              struct cpuidle_device *dev, bool *dummy)
 {
        struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
        struct device *device = get_cpu_device(dev->cpu);
 
 struct menu_device {
        int             last_state_idx;
        int             needs_update;
+       int             tick_wakeup;
 
        unsigned int    next_timer_us;
        unsigned int    predicted_us;
  * menu_select - selects the next idle state to enter
  * @drv: cpuidle driver containing state data
  * @dev: the CPU
+ * @stop_tick: indication on whether or not to stop the tick
  */
-static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
+static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+                      bool *stop_tick)
 {
        struct menu_device *data = this_cpu_ptr(&menu_devices);
        struct device *device = get_cpu_device(dev->cpu);
                latency_req = resume_latency;
 
        /* Special case when user has set very strict latency requirement */
-       if (unlikely(latency_req == 0))
+       if (unlikely(latency_req == 0)) {
+               *stop_tick = false;
                return 0;
+       }
 
        /* determine the expected residency time, round up */
        data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length());
        if (latency_req > interactivity_req)
                latency_req = interactivity_req;
 
+       expected_interval = data->predicted_us;
        /*
         * Find the idle state with the lowest power while satisfying
         * our constraints.
                        idx = i; /* first enabled state */
                if (s->target_residency > data->predicted_us)
                        break;
-               if (s->exit_latency > latency_req)
+               if (s->exit_latency > latency_req) {
+                       /*
+                        * If we break out of the loop for latency reasons, use
+                        * the target residency of the selected state as the
+                        * expected idle duration so that the tick is retained
+                        * as long as that target residency is low enough.
+                        */
+                       expected_interval = drv->states[idx].target_residency;
                        break;
-
+               }
                idx = i;
        }
 
        if (idx == -1)
                idx = 0; /* No states enabled. Must use 0. */
 
+       /*
+        * Don't stop the tick if the selected state is a polling one or if the
+        * expected idle duration is shorter than the tick period length.
+        */
+       if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
+           expected_interval < TICK_USEC)
+               *stop_tick = false;
+
        data->last_state_idx = idx;
 
        return data->last_state_idx;
 
        data->last_state_idx = index;
        data->needs_update = 1;
+       data->tick_wakeup = tick_nohz_idle_got_tick();
 }
 
 /**
         * assume the state was never reached and the exit latency is 0.
         */
 
-       /* measured value */
-       measured_us = cpuidle_get_last_residency(dev);
-
-       /* Deduct exit latency */
-       if (measured_us > 2 * target->exit_latency)
-               measured_us -= target->exit_latency;
-       else
-               measured_us /= 2;
+       if (data->tick_wakeup && data->next_timer_us > TICK_USEC) {
+               /*
+                * The nohz code said that there wouldn't be any events within
+                * the tick boundary (if the tick was stopped), but the idle
+                * duration predictor had a differing opinion.  Since the CPU
+                * was woken up by a tick (that wasn't stopped after all), the
+                * predictor was not quite right, so assume that the CPU could
+                * have been idle long (but not forever) to help the idle
+                * duration predictor do a better job next time.
+                */
+               measured_us = 9 * MAX_INTERESTING / 10;
+       } else {
+               /* measured value */
+               measured_us = cpuidle_get_last_residency(dev);
+
+               /* Deduct exit latency */
+               if (measured_us > 2 * target->exit_latency)
+                       measured_us -= target->exit_latency;
+               else
+                       measured_us /= 2;
+       }
 
        /* Make sure our coefficients do not exceed unity */
        if (measured_us > data->next_timer_us)
 
                                  struct cpuidle_device *dev);
 
 extern int cpuidle_select(struct cpuidle_driver *drv,
-                         struct cpuidle_device *dev);
+                         struct cpuidle_device *dev,
+                         bool *stop_tick);
 extern int cpuidle_enter(struct cpuidle_driver *drv,
                         struct cpuidle_device *dev, int index);
 extern void cpuidle_reflect(struct cpuidle_device *dev, int index);
                                         struct cpuidle_device *dev)
 {return true; }
 static inline int cpuidle_select(struct cpuidle_driver *drv,
-                                struct cpuidle_device *dev)
+                                struct cpuidle_device *dev, bool *stop_tick)
 {return -ENODEV; }
 static inline int cpuidle_enter(struct cpuidle_driver *drv,
                                struct cpuidle_device *dev, int index)
                                        struct cpuidle_device *dev);
 
        int  (*select)          (struct cpuidle_driver *drv,
-                                       struct cpuidle_device *dev);
+                                       struct cpuidle_device *dev,
+                                       bool *stop_tick);
        void (*reflect)         (struct cpuidle_device *dev, int index);
 };
 
 
 extern void tick_nohz_idle_enter(void);
 extern void tick_nohz_idle_exit(void);
 extern void tick_nohz_irq_exit(void);
+extern bool tick_nohz_idle_got_tick(void);
 extern ktime_t tick_nohz_get_sleep_length(void);
 extern unsigned long tick_nohz_get_idle_calls(void);
 extern unsigned long tick_nohz_get_idle_calls_cpu(int cpu);
 static inline void tick_nohz_idle_restart_tick(void) { }
 static inline void tick_nohz_idle_enter(void) { }
 static inline void tick_nohz_idle_exit(void) { }
+static inline bool tick_nohz_idle_got_tick(void) { return false; }
 
 static inline ktime_t tick_nohz_get_sleep_length(void)
 {
 
                next_state = cpuidle_find_deepest_state(drv, dev);
                call_cpuidle(drv, dev, next_state);
        } else {
+               bool stop_tick = true;
+
                tick_nohz_idle_stop_tick();
                rcu_idle_enter();
 
                /*
                 * Ask the cpuidle framework to choose a convenient idle state.
                 */
-               next_state = cpuidle_select(drv, dev);
+               next_state = cpuidle_select(drv, dev, &stop_tick);
                entered_state = call_cpuidle(drv, dev, next_state);
                /*
                 * Give the governor an opportunity to reflect on the outcome
 
                tick_nohz_full_update_tick(ts);
 }
 
+/**
+ * tick_nohz_idle_got_tick - Check whether or not the tick handler has run
+ */
+bool tick_nohz_idle_got_tick(void)
+{
+       struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
+
+       if (ts->inidle > 1) {
+               ts->inidle = 1;
+               return true;
+       }
+       return false;
+}
+
 /**
  * tick_nohz_get_sleep_length - return the length of the current sleep
  *
        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);
        struct pt_regs *regs = get_irq_regs();
        ktime_t now = ktime_get();
 
+       if (ts->inidle)
+               ts->inidle = 2;
+
        tick_sched_do_timer(now);
 
        /*