@@ -382,12 +382,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
382382 /* Check if there is any choice in the first place. */
383383 if (drv -> state_count < 2 ) {
384384 idx = 0 ;
385- goto end ;
385+ goto out_tick ;
386386 }
387+
387388 if (!dev -> states_usage [0 ].disable ) {
388389 idx = 0 ;
389390 if (drv -> states [1 ].target_residency_ns > duration_ns )
390- goto end ;
391+ goto out_tick ;
391392 }
392393
393394 cpu_data -> utilized = teo_cpu_is_utilized (dev -> cpu , cpu_data );
@@ -408,11 +409,12 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
408409 * anyway.
409410 */
410411 if ((!idx && !(drv -> states [0 ].flags & CPUIDLE_FLAG_POLLING ) &&
411- teo_time_ok (duration_ns )) || dev -> states_usage [1 ].disable )
412+ teo_time_ok (duration_ns )) || dev -> states_usage [1 ].disable ) {
412413 idx = 0 ;
413- else /* Assume that state 1 is not a polling one and use it. */
414- idx = 1 ;
415-
414+ goto out_tick ;
415+ }
416+ /* Assume that state 1 is not a polling one and use it. */
417+ idx = 1 ;
416418 goto end ;
417419 }
418420
@@ -459,8 +461,15 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
459461 /* Avoid unnecessary overhead. */
460462 if (idx < 0 ) {
461463 idx = 0 ; /* No states enabled, must use 0. */
462- goto end ;
463- } else if (idx == idx0 ) {
464+ goto out_tick ;
465+ }
466+
467+ if (idx == idx0 ) {
468+ /*
469+ * This is the first enabled idle state, so use it, but do not
470+ * allow the tick to be stopped it is shallow enough.
471+ */
472+ duration_ns = drv -> states [idx ].target_residency_ns ;
464473 goto end ;
465474 }
466475
@@ -566,24 +575,25 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
566575
567576end :
568577 /*
569- * Don't stop the tick if the selected state is a polling one or if the
570- * expected idle duration is shorter than the tick period length.
578+ * Allow the tick to be stopped unless the selected state is a polling
579+ * one or the expected idle duration is shorter than the tick period
580+ * length.
571581 */
572- if (((drv -> states [idx ].flags & CPUIDLE_FLAG_POLLING ) ||
573- duration_ns < TICK_NSEC ) && ! tick_nohz_tick_stopped ()) {
574- * stop_tick = false ;
582+ if ((! (drv -> states [idx ].flags & CPUIDLE_FLAG_POLLING ) &&
583+ duration_ns >= TICK_NSEC ) || tick_nohz_tick_stopped ())
584+ return idx ;
575585
576- /*
577- * The tick is not going to be stopped, so if the target
578- * residency of the state to be returned is not within the time
579- * till the closest timer including the tick, try to correct
580- * that.
581- */
582- if (idx > idx0 &&
583- drv -> states [idx ].target_residency_ns > delta_tick )
584- idx = teo_find_shallower_state (drv , dev , idx , delta_tick , false);
585- }
586+ /*
587+ * The tick is not going to be stopped, so if the target residency of
588+ * the state to be returned is not within the time till the closest
589+ * timer including the tick, try to correct that.
590+ */
591+ if (idx > idx0 &&
592+ drv -> states [idx ].target_residency_ns > delta_tick )
593+ idx = teo_find_shallower_state (drv , dev , idx , delta_tick , false);
586594
595+ out_tick :
596+ * stop_tick = false;
587597 return idx ;
588598}
589599
0 commit comments