===================================================================
@@ -397,13 +397,22 @@ static int teo_select(struct cpuidle_dri
* the shallowest non-polling state and exit.
*/
if (drv->state_count < 3 && cpu_data->utilized) {
- for (i = 0; i < drv->state_count; ++i) {
- if (!dev->states_usage[i].disable &&
- !(drv->states[i].flags & CPUIDLE_FLAG_POLLING)) {
- idx = i;
+ /*
+ * If state 0 is enabled and it is not a polling one, select it
+ * right away and update the idle duration estimate accordingly,
+ * unless the scheduler tick has been stopped.
+ */
+ if (!idx && !(drv->states[0].flags & CPUIDLE_FLAG_POLLING)) {
+ s64 span_ns = teo_middle_of_bin(0, drv);
+
+ if (teo_time_ok(span_ns)) {
+ duration_ns = span_ns;
goto end;
}
}
+ /* Assume that state 1 is not a polling one and select it. */
+ idx = 1;
+ goto end;
}
/*
@@ -539,10 +548,20 @@ static int teo_select(struct cpuidle_dri
/*
* If the CPU is being utilized over the threshold, choose a shallower
- * non-polling state to improve latency
+ * non-polling state to improve latency, unless the scheduler tick has
+ * been stopped already and the shallower state's target residency is
+ * not sufficiently large.
*/
- if (cpu_data->utilized)
- idx = teo_find_shallower_state(drv, dev, idx, duration_ns, true);
+ if (cpu_data->utilized) {
+ s64 span_ns;
+
+ i = teo_find_shallower_state(drv, dev, idx, duration_ns, true);
+ span_ns = teo_middle_of_bin(i, drv);
+ if (teo_time_ok(span_ns)) {
+ idx = i;
+ duration_ns = span_ns;
+ }
+ }
end:
/*