英特尔 CPU 在低功耗挂起状态下无法进入比包 C3 状态更深的状态(导致电池耗尽)

英特尔 CPU 在低功耗挂起状态下无法进入比包 C3 状态更深的状态(导致电池耗尽)

在挖掘和搜索了整个网络后,首先是有关 Dell XPS 挂起至空闲 (s2idle、S0、S0ix、Modern Standby) 时电池消耗的问题。此问题在 Windows、Ubuntu 和 Fedora 中仍然存在,其中 CPU C 状态下降到 C7%,但程序包从未深入到 C3,这导致巨大的电池消耗(当前功耗约为 5W/h,这太疯狂了)

从 Linux 操作系统获取更多信息后,我得到的误导性信息与包 C 状态有关。其中 current_driver 显示为 intel_idle,但状态以 Cx_ACPI 命名,并且没有实际的 intel_idle 驱动程序名称(C1、C2、...C10),ACPI 状态名称仅显示到 C3_ACPI,如下所示:

$ grep . /sys/devices/system/cpu/cpu0/cpuidle/state*/name
/sys/devices/system/cpu/cpu0/cpuidle/state0/name:POLL
/sys/devices/system/cpu/cpu0/cpuidle/state1/name:C1_ACPI
/sys/devices/system/cpu/cpu0/cpuidle/state2/name:C2_ACPI
/sys/devices/system/cpu/cpu0/cpuidle/state3/name:C3_ACPI
$ cat /sys/kernel/debug/pmc_core/package_cstate_show
Package C2 : 84450916
Package C3 : 496526337
Package C6 : 0
Package C7 : 0
Package C8 : 0
Package C9 : 0
Package C10 : 0

current_drivers 显示 intel_idle 驱动程序:

$ cat /sys/devices/system/cpu/cpuidle/current_driver
intel_idle

我搜索过的大多数线程和地方都显示如下输出:

/sys/devices/system/cpu/cpu0/cpuidle/state0/name:POLL
/sys/devices/system/cpu/cpu0/cpuidle/state1/name:C1
/sys/devices/system/cpu/cpu0/cpuidle/state2/name:C1E
/sys/devices/system/cpu/cpu0/cpuidle/state3/name:C3
/sys/devices/system/cpu/cpu0/cpuidle/state4/name:C6
/sys/devices/system/cpu/cpu0/cpuidle/state5/name:C7s
/sys/devices/system/cpu/cpu0/cpuidle/state6/name:C8
/sys/devices/system/cpu/cpu0/cpuidle/state7/name:C9
/sys/devices/system/cpu/cpu0/cpuidle/state8/name:C10

我相信如果我能够将此 ACPI 空闲状态解决为实际的英特尔驱动程序,S0 将正常工作。

有没有人遇到同样的问题或已经解决了?

顺便说一下,这是一台戴尔 XPS 9510 i7 11800H 3050Ti

答案1

这个问题经常出现,但我认为实际上并没有什么问题,这也不是耗电量过多的根源。

对于 Intel 处理器,空闲状态名称是默认的 ACPI 相关名称,或者是更详细的 Intel 名称,具体取决于 Intel 是否已在内核源代码树文件中定义该特定处理器使用它们drivers/idle/intel_idle.c。以下是代码片段:

static const struct x86_cpu_id intel_idle_ids[] __initconst = {
        X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP,          &idle_cpu_nhx),
        X86_MATCH_INTEL_FAM6_MODEL(NEHALEM,             &idle_cpu_nehalem),
        ...
        X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT,        &idle_cpu_cht),
        X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE,           &idle_cpu_ivb),
        ...
        X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L,           &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE,             &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L,          &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE,            &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X,           &idle_cpu_skx),
        X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X,           &idle_cpu_icx),
        X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D,           &idle_cpu_icx),
        X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,           &idle_cpu_adl),
        X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,         &idle_cpu_adl_l),
        ...

有些处理器不在该列表中,例如“Comet Lake”和“Tiger Lake”。必须查看该desc字段才能进一步了解与实际空闲状态的映射。例如(Comet Lake 处理器):

$ grep . /sys/devices/system/cpu/cpu0/cpuidle/state*/desc
/sys/devices/system/cpu/cpu0/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
/sys/devices/system/cpu/cpu0/cpuidle/state1/desc:ACPI FFH MWAIT 0x0
/sys/devices/system/cpu/cpu0/cpuidle/state2/desc:ACPI FFH MWAIT 0x30
/sys/devices/system/cpu/cpu0/cpuidle/state3/desc:ACPI FFH MWAIT 0x60

如果使用此补丁重新编译内核:

$ git diff
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index bcf1198e8991..54259172f6fe 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1522,6 +1522,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
        X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D,         &idle_cpu_bdx),
        X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L,           &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE,             &idle_cpu_skl),
+       X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE,           &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L,          &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE,            &idle_cpu_skl),
        X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X,           &idle_cpu_skx),

然后我们得到这个:

$ grep . /sys/devices/system/cpu/cpu0/cpuidle/state*/desc
/sys/devices/system/cpu/cpu0/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
/sys/devices/system/cpu/cpu0/cpuidle/state1/desc:MWAIT 0x00
/sys/devices/system/cpu/cpu0/cpuidle/state2/desc:MWAIT 0x01
/sys/devices/system/cpu/cpu0/cpuidle/state3/desc:MWAIT 0x10
/sys/devices/system/cpu/cpu0/cpuidle/state4/desc:MWAIT 0x20
/sys/devices/system/cpu/cpu0/cpuidle/state5/desc:MWAIT 0x33
/sys/devices/system/cpu/cpu0/cpuidle/state6/desc:MWAIT 0x40
/sys/devices/system/cpu/cpu0/cpuidle/state7/desc:MWAIT 0x50
/sys/devices/system/cpu/cpu0/cpuidle/state8/desc:MWAIT 0x60
$ grep . /sys/devices/system/cpu/cpu0/cpuidle/state*/name
/sys/devices/system/cpu/cpu0/cpuidle/state0/name:POLL
/sys/devices/system/cpu/cpu0/cpuidle/state1/name:C1
/sys/devices/system/cpu/cpu0/cpuidle/state2/name:C1E
/sys/devices/system/cpu/cpu0/cpuidle/state3/name:C3
/sys/devices/system/cpu/cpu0/cpuidle/state4/name:C6
/sys/devices/system/cpu/cpu0/cpuidle/state5/name:C7s
/sys/devices/system/cpu/cpu0/cpuidle/state6/name:C8
/sys/devices/system/cpu/cpu0/cpuidle/state7/name:C9
/sys/devices/system/cpu/cpu0/cpuidle/state8/name:C10

最深的空闲状态同样深,空闲处理器功率也类似:

doug@s19:~$ sudo turbostat --quiet --Summary --show Busy%,Bzy_MHz,IRQ,PkgWatt,PkgTmp,RAMWatt,GFXWatt,CorWatt --interval 60
[sudo] password for doug:
Busy%   Bzy_MHz IRQ     PkgTmp  PkgWatt CorWatt GFXWatt RAMWatt
0.01    1095    1826    39      2.05    1.32    0.00    1.34
0.02    800     1639    39      1.99    1.28    0.00    1.34
0.05    3393    2746    38      2.05    1.39    0.00    1.33
0.04    2972    2305    39      2.06    1.41    0.00    1.33
0.05    3325    2828    39      2.06    1.41    0.00    1.33 

作为参考,原始内核:

$ sudo turbostat --quiet --Summary --show Busy%,Bzy_MHz,IRQ,PkgWatt,PkgTmp,RAMWatt,GFXWatt,CorWatt --interval 60
Busy%   Bzy_MHz IRQ     PkgTmp  PkgWatt CorWatt GFXWatt RAMWatt
0.03    3233    2345    37      2.17    1.51    0.00    1.33
0.04    3277    2680    37      2.02    1.37    0.00    1.33
0.04    3324    2695    37      2.07    1.41    0.00    1.33
0.04    3151    2706    37      2.03    1.37    0.00    1.33
0.03    3018    2251    37      1.96    1.30    0.00    1.33
0.04    3111    2878    37      2.01    1.36    0.00    1.33

编辑:从评论来看,处理器似乎只有空闲深度MWAIT 0x20可用。通过禁用更深的空闲状态在我的测试服务器上重现该情况,仍然没有将处理器封装功率增加到可检测的量:

root@s19:/home/doug# /home/doug/kernel/linux/tools/power/x86/turbostat/turbostat --quiet --Summary --show Busy%,Bzy_MHz,PkgWatt,PkgTmp,RAMWatt,GFXWatt,POLL%,C1%,C1E%,C3%,C6%,C7s%,C8%,C9%,C10%,CorWatt --interval 60
Busy%   Bzy_MHz POLL%   C1%     C1E%    C3%     C6%     C7s%    C8%     C9%     C10%    PkgTmp  PkgWatt CorWatt GFXWatt RAMWatt
0.04    3157    0.00    0.01    3.02    0.26    96.67   0.00    0.00    0.00    0.00    37      2.03    1.37    0.00    1.33
0.05    3425    0.00    0.01    5.48    0.23    94.22   0.00    0.00    0.00    0.00    37      2.13    1.47    0.00    1.33
0.05    3354    0.00    0.01    6.02    0.27    93.65   0.00    0.00    0.00    0.00    37      2.07    1.41    0.00    1.33
0.05    3412    0.00    0.01    1.70    0.61    97.63   0.00    0.00    0.00    0.00    37      2.06    1.41    0.00    1.33
0.05    3569    0.00    0.01    2.69    0.39    96.86   0.00    0.00    0.00    0.00    37      2.11    1.45    0.00    1.33

相关内容