[Bug 432809] New: C1 state unsupported on modern AMD mobile CPUs
https://bugzilla.novell.com/show_bug.cgi?id=432809 Summary: C1 state unsupported on modern AMD mobile CPUs Product: openSUSE 11.0 Version: Final Platform: Other OS/Version: openSUSE 11.0 Status: NEW Severity: Normal Priority: P5 - None Component: Kernel AssignedTo: bnc-team-screening@forge.provo.novell.com ReportedBy: jakub007@go2.pl QAContact: qa@suse.de Found By: Corporate Interoperability Test Newer laptops with AMD Turion X2 and AMD Athlon X2 mobile processors (which are C1E capable) are overheating and have very degraded battery life due to bugs in /usr/src/linux/drivers/acpi/processor_idle.c (not properly implemented C1 support). C1E replaces C2 and C3 states, so BIOS usually doesn't have definitions for _CST and PBLK in FADT - it is valid according to ACPI specification. Here is MS info about PPM in Vista: http://download.microsoft.com/download/0/0/b/00bba048-35e6-4e5b-a3dc-36da83c... Below is patch which fixes C1 visibility, but doesn't increase battery life to Vista level. --- cut here -- --- kernels/linux-2.6.27-rc8/drivers/acpi/processor_idle.c 2008-09-30 00:24:02.000000000 +0200 +++ linux/drivers/acpi/processor_idle.c 2008-10-06 00:24:19.000000000 +0200 @@ -501,7 +501,7 @@ * ------ * Invoke the current Cx state to put the processor to sleep. */ - if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { + if (cx->type >= ACPI_STATE_C1) { current_thread_info()->status &= ~TS_POLLING; /* * TS_POLLING-cleared state must be visible before we @@ -523,12 +523,17 @@ * Use the appropriate idle routine, the one that would * be used without acpi C-states. */ + + t1 = jiffies; + if (pm_idle_save) { pm_idle_save(); /* enables IRQs */ } else { acpi_safe_halt(); local_irq_enable(); } + + t2 = jiffies; /* * TBD: Can't get time duration while in C1, as resumes @@ -538,8 +543,7 @@ * Note: the TSC better not stop in C1, sched_clock() will * skew otherwise. */ - sleep_ticks = 0xFFFFFFFF; - + sleep_ticks = ticks_elapsed(t1, t2); break; case ACPI_STATE_C2: @@ -642,12 +646,13 @@ return; } cx->usage++; - if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0)) + if (cx->type != ACPI_STATE_C1 && sleep_ticks > 0) cx->time += sleep_ticks; next_state = pr->power.state; #ifdef CONFIG_HOTPLUG_CPU + /* Don't do promotion/demotion */ if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { @@ -811,8 +816,11 @@ if (!pr) return -EINVAL; + /* Newer dual-core CPUs use C1E instead of C2 and C3 and + * usually do not have _CST definitions or PBLK entries. + * ACPI specification allows for that so return zero here */ if (!pr->pblk) - return -ENODEV; + return 0; /* if info is obtained from pblk/fadt, type equals state */ pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; @@ -852,6 +860,11 @@ pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; pr->power.states[ACPI_STATE_C1].valid = 1; pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT; + snprintf(pr->power.states[ACPI_STATE_C1].desc, ACPI_CX_DESC_LEN, "ACPI HLT"); + if (!pr->power.states[ACPI_STATE_C1].latency) + pr->power.states[ACPI_STATE_C1].latency = 1; + if (!pr->power.states[ACPI_STATE_C1].power) + pr->power.states[ACPI_STATE_C1].power = 1000; } /* the C0 state only exists as a filler in our array */ pr->power.states[ACPI_STATE_C0].valid = 1; @@ -1191,12 +1204,11 @@ memset(pr->power.states, 0, sizeof(pr->power.states)); result = acpi_processor_get_power_info_cst(pr); - if (result == -ENODEV) - result = acpi_processor_get_power_info_fadt(pr); - if (result) - return result; + result = acpi_processor_get_power_info_fadt(pr); + /* No valid _CST and FADT, but C1 must be supported, + * so here we go */ acpi_processor_get_power_info_default(pr); pr->power.count = acpi_processor_power_verify(pr); @@ -1216,13 +1228,13 @@ #endif /* - * if one state of type C2 or C3 is available, mark this + * if one state of type C1(e), C2 or C3 is available, mark this * CPU as being "idle manageable" */ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { if (pr->power.states[i].valid) { pr->power.count = i; - if (pr->power.states[i].type >= ACPI_STATE_C2) + if (pr->power.states[i].type >= ACPI_STATE_C1) pr->flags.power = 1; } } @@ -1455,7 +1467,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, struct cpuidle_state *state) { - u32 t1, t2; + u32 t1, t2, elapsed; struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); @@ -1482,7 +1494,10 @@ local_irq_enable(); cx->usage++; - + elapsed = ticks_elapsed(t1, t2); + if (elapsed > 0) + cx->time += elapsed; + return ticks_elapsed_in_us(t1, t2); } -- cut here -- -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.
https://bugzilla.novell.com/show_bug.cgi?id=432809
Andreas Jaeger
https://bugzilla.novell.com/show_bug.cgi?id=432809
User trenn@novell.com added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c1
Thomas Renninger
but doesn't increase battery life to Vista level Do you see power savings at all and if how much about?
I have several questions about this, IMO this should be discussed via mail first. -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.
https://bugzilla.novell.com/show_bug.cgi?id=432809
User trenn@novell.com added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c2
Thomas Renninger
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c3
--- Comment #3 from Jakub Jozwicki
Have you or has this patch been posted upstream? Discussing patches in bugzilla is ugly, best would be you post that upstream (lkml and acpi-linux) and CC me.
Hello, For me sending my own patches to lkml doesn't have a sense. Long time ago I had sent patches for enabling UDMA100 on Asus A6K and Acer Aspire 3680 and these patches were ignored. I had filled bug report in SuSE bugzilla and the same patches signed by SuSE people were accepted. If you are not top committer you are ignored. I had the same bad experience with patches fixing -rt kernel.
Jakub, I am very interested in this one. I always was sure C1 is entered on these (should be hlt instruction >if no other C-states are found?).
You may want to mail me privately, adding Joachim from AMD if you do >not
Let's assume this kind of situation: Laptop manufacturer knows that Turion X2 or mobile Athlon X2 supports C1(e). He doesn't add _CST and FADT entries in DSDT, since C1 is always supported on any CPU (in the theory). Now if you look at processor_idle.c : acpi_processor_get_power_info you see that: a) if there is no _CST we return from _get_power_info_cst with error and enter _get_power_info_dsdt b) if P_BLK address is zero we return from _get_power_info_dsdt with error and exit with error the whole _get_power_info function without marking that C1 is supported. If normal idle function is the same as C1 handling then mine patch doesn't have any sense (except enabling visibility of C1 in Powertop). From the other side I have checked with Windows Driver Kit for Vista and pwrtest.exe that my CPU on Windows Server 2008 uses C1 above 90% of the time while reading slashdot or osnews and battery life is above 3 hours. The same activity on OpenSUSE 11.0, 11.1 beta2 - battery lives 1h 40 min. The are no miracles - either W2K8 has some marvelous power management or power management in linux is broken. like to post that on lkml and linux-acpi directly. I've been trying to ask tech.support@amd.com for some technical help, but I was told that 'Linux is not officially supported'... -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c4
--- Comment #4 from Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c5
--- Comment #5 from Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c6
--- Comment #6 from Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c7
--- Comment #7 from Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User trenn@novell.com added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c8
--- Comment #8 from Thomas Renninger
I've been trying to ask tech.support@amd.com for some technical help, but I was told that 'Linux is not officially supported'... Yeah, but this is practically for every Windows only supported model. I mean it's the support, they have to ask you this and then say good bye if the answer is Linux.
Joachim told me he has some news for C1E for me. He could add you into CC if you are interested. It is great to see people getting involved. -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c9
--- Comment #9 from Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c10
Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c11
--- Comment #11 from Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User jakub007@go2.pl added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c12
Jakub Jozwicki
https://bugzilla.novell.com/show_bug.cgi?id=432809
User trenn@novell.com added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c13
Thomas Renninger
Is there other way to enable C1E? Only via BIOS setting.
Theoretically you could try to switch it on via msr writes, but you shouldn't override your BIOS settings. You can use rdmsr and wrmsr from the msr-tools package on Linux to find out more about the C1E settings of your machine. -> this is not a Linux issue -> closing invalid. -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.
https://bugzilla.novell.com/show_bug.cgi?id=432809
User trenn@novell.com added comment
https://bugzilla.novell.com/show_bug.cgi?id=432809#c14
--- Comment #14 from Thomas Renninger
participants (1)
-
bugzilla_noreply@novell.com