cpuidle: fix 100% C0 statistics regression
authorVenki Pallipadi <venkatesh.pallipadi@intel.com>
Fri, 29 Feb 2008 18:24:32 +0000 (10:24 -0800)
committerLen Brown <len.brown@intel.com>
Wed, 26 Mar 2008 04:58:19 +0000 (00:58 -0400)
commit 9b12e18cdc1553de62d931e73443c806347cd974
'ACPI: cpuidle: Support C1 idle time accounting'
was implicated in a 100% C0 idle regression.
http://bugzilla.kernel.org/show_bug.cgi?id=10076

It pointed out a potential problem where the menu governor
may get confused by the C-state residency time from poll
idle or C1 idle, where this timing info is not accurate.
This inaccuracy is due to interrupts being handled
before we account for C-state exit.

Do not mark TIME_VALID for CO poll state.
Mark C1 time as valid only with the MWAIT (CSTATE_FFH) entry method.

This makes governors use the timing information only when it is correct and
eliminates any wrong policy decisions that may result from invalid timing
information.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/processor_idle.c
drivers/cpuidle/cpuidle.c

index 1468f1e92cac4b69110f29e7a03ac079894d8486..788da9781f80ffb5311b396cd3557b0786376dcd 100644 (file)
@@ -1693,7 +1693,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                switch (cx->type) {
                        case ACPI_STATE_C1:
                        state->flags |= CPUIDLE_FLAG_SHALLOW;
                switch (cx->type) {
                        case ACPI_STATE_C1:
                        state->flags |= CPUIDLE_FLAG_SHALLOW;
-                       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+                       if (cx->entry_method == ACPI_CSTATE_FFH)
+                               state->flags |= CPUIDLE_FLAG_TIME_VALID;
+
                        state->enter = acpi_idle_enter_c1;
                        dev->safe_state = state;
                        break;
                        state->enter = acpi_idle_enter_c1;
                        dev->safe_state = state;
                        break;
index d42deb310ac71fe6f5de6406f740bcda904cea0d..fc555a90bb211b651e20c254751ae08f00fffd1a 100644 (file)
@@ -224,7 +224,7 @@ static void poll_idle_init(struct cpuidle_device *dev)
        state->exit_latency = 0;
        state->target_residency = 0;
        state->power_usage = -1;
        state->exit_latency = 0;
        state->target_residency = 0;
        state->power_usage = -1;
-       state->flags = CPUIDLE_FLAG_POLL | CPUIDLE_FLAG_TIME_VALID;
+       state->flags = CPUIDLE_FLAG_POLL;
        state->enter = poll_idle;
 }
 #else
        state->enter = poll_idle;
 }
 #else