为什么intel_idle不支持某些Intel 6系列CPU模型(Core 2,Pentium M)?


25

我一直在为Intel Core 2 Quad(Yorkfield)处理器调整Linux内核,我注意到以下消息dmesg

[    0.019526] cpuidle: using governor menu
[    0.531691] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    0.550918] intel_idle: does not run on family 6 model 23
[    0.554415] tsc: Marking TSC unstable due to TSC halts in idle

PowerTop仅显示用于封装和单个内核的状态C1,C2和C3:

          Package   |            CPU 0
POLL        0.0%    | POLL        0.0%    0.1 ms
C1          0.0%    | C1          0.0%    0.0 ms
C2          8.2%    | C2          9.9%    0.4 ms
C3         84.9%    | C3         82.5%    0.9 ms

                    |            CPU 1
                    | POLL        0.1%    1.6 ms
                    | C1          0.0%    1.5 ms
                    | C2          9.6%    0.4 ms
                    | C3         82.7%    1.0 ms

                    |            CPU 2
                    | POLL        0.0%    0.1 ms
                    | C1          0.0%    0.0 ms
                    | C2          7.2%    0.3 ms
                    | C3         86.5%    1.0 ms

                    |            CPU 3
                    | POLL        0.0%    0.1 ms
                    | C1          0.0%    0.0 ms
                    | C2          5.9%    0.3 ms
                    | C3         87.7%    1.0 ms

很好奇,我查询sysfs并发现旧版acpi_idle驱动程序正在使用中(我希望看到该intel_idle驱动程序):

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

acpi_idle

查看内核源代码,当前的intel_idle驱动程序包含一条调试消息,专门指出该驱动程序不支持某些Intel 6系列型号:

if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 == 6)
    pr_debug("does not run on family %d model %d\n", boot_cpu_data.x86, boot_cpu_data.x86_model);

intel_idle.c的早期分支(2010年11月22日)显示了对Core 2处理器的预期支持(模型23实际上涵盖了Core 2 Duo和Quad):

#ifdef FUTURE_USE
    case 0x17:  /* 23 - Core 2 Duo */
        lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
#endif

上面的代码已在2010年12月commit中删除。

不幸的是,源代码中几乎没有文档,因此没有解释这些CPU中缺少对空闲功能的支持。

我当前的内核配置如下:

CONFIG_SMP=y
CONFIG_MCORE2=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ACPI_PROCESSOR_IDLE=y
CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
CONFIG_INTEL_IDLE=y

我的问题如下:

  • 是否有特定的硬件原因不支持Core 2处理器intel_idle
  • 是否有更合适的方法来配置内核,以为此处理器家族提供最佳的CPU空闲支持(除了禁用intel_idle)?

Answers:


28

在研究Core 2 CPU的电源状态(“ C状态 ”)时,我实际上设法实现了对大多数传统Intel Core / Core 2处理器的支持。此处记录了具有所有背景信息的完整实现(Linux补丁)。

当我积累了有关这些处理器的更多信息时,很明显,Core 2模型所支持的C状态要比早期和以后的处理器中的C状态复杂得多。这些被称为增强型C状态(或“ CxE ”),涉及封装,芯片组(例如内存)上的各个内核和其他组件。在intel_idle发布驱动程序时,代码并不是特别成熟,并且已经发布了几个具有冲突的C状态支持的Core 2处理器。

从2006年开始的这篇文章中找到了一些有关Core 2 Solo / Duo C状态支持的令人信服的信息。这与Windows上的支持有关,但是它确实表明了这些处理器上强大的硬件C状态支持。有关Kentsfield的信息与实际型号冲突,因此我认为它们实际上是指以下的Yorkfield:

...四核Intel Core 2 Extreme(Kentsfield)处理器支持所有五项性能和节能技术-增强的Intel SpeedStep(EIST),Thermal Monitor 1(TM1)和Thermal Monitor 2(TM2),旧的按需时钟调制(ODCM)以及增强的C状态(CxE)。与仅以增强暂停(C1)状态为特征的Intel Pentium 4和Pentium D 600、800和900处理器相比,此功能在Intel Core 2处理器(以及Intel Core Solo / Duo处理器)中得到了扩展。处理器的所有可能的空闲状态,包括停止授权(C2),深度睡眠(C3)和深度睡眠(C4)。

2008年的这篇文章概述了对多核Intel处理器(包括Core 2 Duo和Core 2 Quad)的每核C状态的支持(在本白皮书中来自Dell,还有其他有用的背景知识):

核心C状态是硬件C状态。有几个核心空闲状态,例如CC1和CC3。众所周知,现代的处理器具有多个内核,例如最近发布的Core Duo T5000 / T7000移动处理器,在某些领域被称为Penryn。我们以前认为是CPU /处理器的东西实际上实际上有多个通用CPU。英特尔酷睿双核处理器芯片中有2个内核。英特尔酷睿2四核每个处理器芯片具有4个这样的内核。这些内核中的每个内核都有其自己的空闲状态。这很有意义,因为一个核心可能处于空闲状态,而另一个核心可能很难在线程上工作。因此,核心C状态是这些核心之一的空闲状态。

我在Intel2010年演讲中找到了有关该intel_idle驱动程序的其他背景知识,但不幸的是,这并不能解释缺少对Core 2的支持的原因。

此实验驱动程序取代了acpi_idle,它们位于Intel Atom处理器,Intel Core i3 / i5 / i7处理器以及相关的Intel Xeon处理器上。它不支持Intel Core2处理器或更早的版本。

上面的演示确实表明该intel_idle驱动程序是“菜单” CPU调控器的实现,这对Linux内核配置(即CONFIG_CPU_IDLE_GOV_LADDERvs. CONFIG_CPU_IDLE_GOV_MENU)有影响。在此答案中简要描述了梯形调速器和菜单调速器之间的差异。

戴尔有一篇有用的文章,列出了C状态C0到C6的兼容性:

模式C1至C3通过基本切断CPU内部使用的时钟信号来工作,而模式C4至C6通过降低CPU电压来工作。“增强”模式可以同时进行。

Mode   Name                   CPUs
C0     Operating State        All CPUs
C1     Halt                   486DX4 and above
C1E    Enhanced Halt          All socket LGA775 CPUs
C1E    —                      Turion 64, 65-nm Athlon X2 and Phenom CPUs
C2     Stop Grant             486DX4 and above
C2     Stop Clock             Only 486DX4, Pentium, Pentium MMX, K5, K6, K6-2, K6-III
C2E    Extended Stop Grant    Core 2 Duo and above (Intel only)
C3     Sleep                  Pentium II, Athlon and above, but not on Core 2 Duo E4000 and E6000
C3     Deep Sleep             Pentium II and above, but not on Core 2 Duo E4000 and E6000; Turion 64
C3     AltVID                 AMD Turion 64
C4     Deeper Sleep           Pentium M and above, but not on Core 2 Duo E4000 and E6000 series; AMD Turion 64
C4E/C5 Enhanced Deeper Sleep  Core Solo, Core Duo and 45-nm mobile Core 2 Duo only
C6     Deep Power Down        45-nm mobile Core 2 Duo only

从此表中(我后来发现在某些情况下是不正确的),似乎对Core 2处理器的C状态支持存在多种差异(请注意,除Core之外,几乎所有Core 2处理器都是Socket LGA775。 2 Solo SU3500,它是Socket BGA956和Merom / Penryn处理器。“ Intel Core” Solo / Duo处理器是Socket PBGA479或PPGA478之一。

本文中找到了表的另一个例外:

英特尔的Core 2 Duo E8500支持C状态C2和C4,而Core 2 Extreme QX9650不支持。

有趣的是,QX9650是Yorkfield处理器(英特尔家族6,型号23,步进6)。作为参考,我的Q9550S是Intel系列6,型号23(0x17),步进10,据称支持C状态C4(通过实验确认)。此外,Core 2 Solo U3500具有与Q9550S相同的CPUID(系列,型号,步进),但在非LGA775插槽中可用,这混淆了上表的解释。

显然,必须使用CPUID至少直到步进为止,以识别对此处理器模型的C状态支持,并且在某些情况下可能不够用(此时尚不确定)。

分配CPU空闲信息的方法签名为:

#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }

model在枚举ASM / Intel的family.h。检查此头文件,我发现为Intel CPU分配了8位标识符,这些标识符似乎与Intel家族6型号匹配:

#define INTEL_FAM6_CORE2_PENRYN 0x17

综上所述,我们将英特尔家族6,模型23(0x17)定义为INTEL_FAM6_CORE2_PENRYN。这足以为大多数Model 23处理器定义空闲状态,但如上所述可能会导致QX9650出现问题。

因此,至少需要在此列表中定义具有不同C状态集的每组处理器。

Zagacki和Ponnala在2008年英特尔技术期刊 12(3):219-227中指出,Yorkfield处理器确实支持C2和C4。它们似乎也表明ACPI 3.0a规范仅支持C状态C0,C1,C2和C3之间的转换,我想这也可能会限制Linux acpi_idle驱动程序在有限的C状态集之间进行转换。但是,本文指出可能并非总是这样:

请记住,这是ACPI C状态,而不是处理器状态,因此ACPI C3可能是硬件C6,依此类推。

还要注意:

除了处理器本身之外,由于C4是平台中主要芯片组件之间的同步工作,因此Intel Q45 Express芯片组可将功耗提高28%。

我使用的芯片组确实是Intel Q45 Express芯片组。

上MWAIT状态Intel文档是简洁,但确认了特定的BIOS的ACPI行为:

在MWAIT扩展中定义的特定于处理器的C状态可以映射到ACPI定义的C状态类型(C0,C1,C2,C3)。映射关系取决于处理器实现对C状态的定义,并由BIOS使用ACPI定义的_CST表向OSPM公开。

我对上面的表(结合Wikipedia的表asm / intel-family.h和上面的文章的解释)是:

型号9 0x09(奔腾M赛扬M):

  • 巴尼亚斯:C0,C1,C2,C3,C4

型号13 0x0D(Pentium MCeleron M):

  • Dothan,Steeley:C0,C1,C2,C3,C4

型号14 0x0E INTEL_FAM6_CORE_YONAH(增强的Pentium M增强的Celeron MIntel Core):

  • Yonah(Core SoloCore Duo):C0,C1,C2,C3,C4,C4E / C5

型号15 0x0F INTEL_FAM6_CORE2_MEROM(某些Core 2Pentium Dual-Core):

  • Kentsfield,Merom,Conroe,Allendale(E2xxx / E4xxxCore 2 Duo E6xxx,T7xxxx / T8xxxxCore 2 Extreme QX6xxxCore 2 Quad Q6xxx):C0,C1,C1E,C2,C2E

型号23 0x17 INTEL_FAM6_CORE2_PENRYN(核心2):

  • Merom-L / Penryn-L :?
  • Penryn(Core 2 Duo 45-nm mobile):C0,C1,C1E,C2,C2E,C3,C4,C4E / C5,C6
  • 约克菲尔德(Core 2 Extreme QX9650):C0,C1,C1E,C2E ?, C3
  • Wolfdale / Yorkfield(Core 2 QuadC2Q XeonCore 2 Duo E5xxx / E7xxx / E8xxxPentium Dual-Core E6xxxCeleron Dual-Core):C0,C1,C1E,C2,C2E,C3,C4

从仅Core 2系列处理器对C状态支持的多样性来看,似乎缺乏对C状态的一致支持可能是未尝试通过intel_idle驱动程序完全支持它们的原因。我想完整地完成整个Core 2产品线的上述清单。

这并不是一个令人满意的答案,因为这使我想知道,由于没有充分利用这些处理器上强大的省电MWAIT C状态,因此使用了多少不必要的功率,并且已经(并且仍然)产生了多余的热量。

Chattopadhyay 等。2018年,《高效能高性能处理器:设计绿色高性能计算的最新方法》因我在Q45 Express芯片组中寻找的特定行为而值得注意:

程序包C状态(PC0-PC10)-当计算域,核心和图形(GPU)处于空闲状态时,处理器将有机会在非核心和平台级别上进一步节省功耗,例如,冲洗LLC并对其进行电源门控存储器控制器和DRAM IO,并且在某些状态下,可以关闭整个处理器,同时将其状态保留在始终在线的电源域中。

作为测试,我在linux / drivers / idle / intel_idle.c第127行中插入了以下内容:

static struct cpuidle_state conroe_cstates[] = {
    {
        .name = "C1",
        .desc = "MWAIT 0x00",
        .flags = MWAIT2flg(0x00),
        .exit_latency = 3,
        .target_residency = 6,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C1E",
        .desc = "MWAIT 0x01",
        .flags = MWAIT2flg(0x01),
        .exit_latency = 10,
        .target_residency = 20,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
//  {
//      .name = "C2",
//      .desc = "MWAIT 0x10",
//      .flags = MWAIT2flg(0x10),
//      .exit_latency = 20,
//      .target_residency = 40,
//      .enter = &intel_idle,
//      .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C2E",
        .desc = "MWAIT 0x11",
        .flags = MWAIT2flg(0x11),
        .exit_latency = 40,
        .target_residency = 100,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .enter = NULL }
};

static struct cpuidle_state core2_cstates[] = {
    {
        .name = "C1",
        .desc = "MWAIT 0x00",
        .flags = MWAIT2flg(0x00),
        .exit_latency = 3,
        .target_residency = 6,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C1E",
        .desc = "MWAIT 0x01",
        .flags = MWAIT2flg(0x01),
        .exit_latency = 10,
        .target_residency = 20,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C2",
        .desc = "MWAIT 0x10",
        .flags = MWAIT2flg(0x10),
        .exit_latency = 20,
        .target_residency = 40,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C2E",
        .desc = "MWAIT 0x11",
        .flags = MWAIT2flg(0x11),
        .exit_latency = 40,
        .target_residency = 100,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C3",
        .desc = "MWAIT 0x20",
        .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 85,
        .target_residency = 200,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C4",
        .desc = "MWAIT 0x30",
        .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 100,
        .target_residency = 400,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C4E",
        .desc = "MWAIT 0x31",
        .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 100,
        .target_residency = 400,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C6",
        .desc = "MWAIT 0x40",
        .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 200,
        .target_residency = 800,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .enter = NULL }
};

intel_idle.c983行:

static const struct idle_cpu idle_cpu_conroe = {
    .state_table = conroe_cstates,
    .disable_promotion_to_c1e = false,
};

static const struct idle_cpu idle_cpu_core2 = {
    .state_table = core2_cstates,
    .disable_promotion_to_c1e = false,
};

intel_idle.c1073行:

ICPU(INTEL_FAM6_CORE2_MEROM,  idle_cpu_conroe),
ICPU(INTEL_FAM6_CORE2_PENRYN, idle_cpu_core2),

快速编译并重新启动我的PXE节点后,dmesg现在显示:

[    0.019845] cpuidle: using governor menu
[    0.515785] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    0.543404] intel_idle: MWAIT substates: 0x22220
[    0.543405] intel_idle: v0.4.1 model 0x17
[    0.543413] tsc: Marking TSC unstable due to TSC halts in idle states deeper than C2
[    0.543680] intel_idle: lapic_timer_reliable_states 0x2

现在,PowerTOP显示:

          Package   |            CPU 0
POLL        2.5%    | POLL        0.0%    0.0 ms
C1E         2.9%    | C1E         5.0%   22.4 ms
C2          0.4%    | C2          0.2%    0.2 ms
C3          2.1%    | C3          1.9%    0.5 ms
C4E        89.9%    | C4E        92.6%   66.5 ms

                    |            CPU 1
                    | POLL       10.0%  400.8 ms
                    | C1E         5.1%    6.4 ms
                    | C2          0.3%    0.1 ms
                    | C3          1.4%    0.6 ms
                    | C4E        76.8%   73.6 ms

                    |            CPU 2
                    | POLL        0.0%    0.2 ms
                    | C1E         1.1%    3.7 ms
                    | C2          0.2%    0.2 ms
                    | C3          3.9%    1.3 ms
                    | C4E        93.1%   26.4 ms

                    |            CPU 3
                    | POLL        0.0%    0.7 ms
                    | C1E         0.3%    0.3 ms
                    | C2          1.1%    0.4 ms
                    | C3          1.1%    0.5 ms
                    | C4E        97.0%   45.2 ms

我终于访问了增强型Core 2 C状态,看起来功耗有明显下降-我的8个节点上的电表平均平均降低了至少5%(其中一个节点仍在运行旧内核) ,但我将尝试再次换出内核作为测试。

有关C4E支持的有趣说明-My Yorktown Q9550S处理器似乎支持它(或C4的某些其他子状态),如上所示!这让我感到困惑,因为Core 2 Q9000处理器上Intel数据表(第6.2节)仅提到了C状态:正常(C0),HALT(C1 = 0x00),扩展HALT(C1E = 0x01),停止授权(C2 = 0x10) ,扩展停止授权(C2E = 0x11),睡眠/深度睡眠(C3 = 0x20)和深度睡眠(C4 = 0x30)。这个额外的0x31状态是什么?如果启用状态C2,则使用C4E而不是C4。如果我禁用状态C2(强制状态C2E),则使用C4代替C4E。我怀疑这可能与MWAIT标志有关,但是我尚未找到有关此行为的文档。

我不确定该怎么做:C1E状态似乎代替了C1,C2代替了C2E,C4E代替了C4。我不确定C1 / C1E,C2 / C2E和C4 / C4E是否可以一起使用,intel_idle或者它们是否多余。我在2010年匹兹堡英特尔实验室的演讲中发现了一个笔记,笔记指出过渡是C0-C1-C0-C1E-C0,并进一步说明:

仅当所有核心都在C1E中时才使用C1E

我认为,只有当所有内核都处于C1E状态时,才能在其他组件(例如内存)上进入C1E状态。我还将其等同地应用于C2 / C2E和C4 / C4E状态(尽管C4E被称为“ C4E / C5”,所以我不确定C4E是C4的子状态还是C5是子状态,测试似乎表明C4 / C4E是正确的)。我可以通过注释掉C2状态来强制使用C2E-但是,这将导致使用C4状态代替C4E(这里可能需要做更多的工作)。希望不会有任何缺少状态C2E的模型15或模型23处理器,因为使用上述代码,这些处理器将限于C1 / C1E。

同样,标记,等待时间和驻留值可能可以进行微调,但是仅基于Nehalem空闲值进行有根据的猜测似乎可以正常工作。需要进行更多阅读才能进行任何改进。

我在Core 2 Duo E2220Allendale),双核Pentium E5300Wolfdale),Core 2 Duo E7400Core 2 Duo E8400Wolfdale),Core 2 Quad Q9550SYorkfield)和Core 2 Extreme QX9650上进行了测试,除了上述对状态C2 / C2E和C4 / C4E的偏好之外,没有发现任何问题。

此驱动程序修改不包括:

  • 最初的Core Solo / Core DuoYonah,非Core 2)是6族,模型14。这很好,因为它们支持C4E / C5(增强型深度睡眠)C状态,但不支持C1E / C2E状态,因此需要它们自己的空闲定义。

我能想到的唯一问题是:

  • Core 2 Solo SU3300 / SU3500(Penryn-L)是系列6,型号23,将被此驱动程序检测到。但是,它们不是Socket LGA775,因此它们可能不支持C1E增强的暂停C状态。对于Core 2 Solo ULV U2100 / U2200(Merom-L)同样如此。但是,intel_idle驱动程序似乎基于子状态的硬件支持选择适当的C1 / C1E。
  • 据报道,Core 2 Extreme QX9650(约克菲尔德)不支持C状态C2或C4。我已经在eBay上购买了二手的Optiplex 780和QX9650 Extreme处理器来确认这一点。处理器支持C状态C1和C1E。通过修改该驱动程序,CPU处于状态C1E而不是C1的空闲状态,因此可以节省一些电能。我期望看到C状态C3,但是使用此驱动程序时它不存在,因此我可能需要进一步研究。

我设法从2009年英特尔的演示文稿中找到了有关C状态之间转换(即深度掉电)的幻灯片:

深度掉电技术进入/退出

总而言之,事实证明,没有真正原因导致intel_idle驱动程序中缺少Core 2支持。现在很明显,“ Core 2 Duo”的原始存根代码仅处理C状态C1和C2,这比acpi_idle处理C状态C3 的功能要低得多。一旦知道了要看的地方,就可以轻松实现支持。非常感谢您提供有用的评论和其他答案,如果Amazon在听,您知道将支票发送到哪里。

此更新已提交给github。我很快会通过电子邮件将补丁发送给LKML。

更新:我还设法挖掘了套接字T / LGA775 AllendaleConroe)Core 2 Duo E2220,它是6系列,15型,因此我也对此添加了支持。该模型不支持C状态C4,但支持C1 / C1E和C2 / C2E。这也应该适用于其他基于Conroe的芯片(E4xxx / E6xxx),可能还适用于所有Kentsfield和Merom(非Merom-L)处理器。

更新:我终于找到了一些MWAIT调优资源。此Power vs. Performance文章以及Deeper C状态和增加的延迟博客文章均包含一些有关识别CPU空闲延迟的有用信息。不幸的是,这仅报告那些已编码到内核中的退出延迟(但是,有趣的是,只有处理器支持的那些硬件状态):

# cd /sys/devices/system/cpu/cpu0/cpuidle
# for state in `ls -d state*` ; do echo c-$state `cat $state/name` `cat $state/latency` ; done

c-state0/ POLL 0
c-state1/ C1 3
c-state2/ C1E 10
c-state3/ C2 20
c-state4/ C2E 40
c-state5/ C3 20
c-state6/ C4 60
c-state7/ C4E 100

4
那是很棒的侦探工作!我忘记了C2D / C2Q C状态的复杂性。重新尚未开发的节能,如果你的固件是足够好,那么你仍然应该得到的至少一些C-国的利益通过 acpi_idle和各种性能州长。powertop系统上显示什么状态?
史蒂芬·基特

1
非常好的信息,您是否考虑过向上游Linux内核提出补丁
Lekensteyn

1
“似乎使用了C1E状态来代替C1 ...”(如powertop所示)所使用的状态仅由内核决定,因此,我认为它不会“与MWAIT标志有关”,仅根据状态的顺序以及exit_latency和target_residency选择它。就是说,如果离开状态在测试时似乎没有被使用,我会稍微担心表中的离开状态...万一这些状态实际上没有按预期工作,并且还有其他工作负载模式导致他们正在使用和意外行为的发生。
sourcejedi

1
“过渡是C0-C1-C0-C1E-C0”-我认为这不是对这张幻灯片的很好描述。从内核/ powertop角度来看,所有转换都是从C0或到C0。如果您不在C0中,则不会运行任何指令,因此内核无法观察或请求该CPU上的状态之间的任何转换:-)。正如您所说,内核“菜单”调控器很可能例如直接跳入C1E,而无需先花费任何时间在C1上。
sourcejedi

1
“仅根据Nehalem空闲值进行有根据的猜测似乎可以正常工作”-请注意,这不是让补丁在上游接受的好方法:-P,因为退出延迟一定不能低估,否则我认为您会违反PM_QOS_CPU_DMA_LATENCY,它可能由驱动程序(或用户空间?)设置
sourcejedi

6

我怀疑这可能只是机会和成本的情况。在intel_idle添加之后,似乎已经计划了对Core 2 Duo的支持,但从未完全实现-也许到Intel工程师考虑时,这已经不值得了。该方程式相对复杂:intel_idle需要提供足够的好处acpi_idle以使其值得在此处支持,在CPU上将看到足够数量的“改进”内核...

正如sourcejedi回答所说,驱动程序并没有排除所有6类。intel_idle初始化检查包含在CPU模型列表中的CPU,这些模型基本上涵盖了从Nehalem到Kaby Lake的所有微体系结构。约克菲尔德(Yorkfield)比那儿古老(并且有很大的不同-Nehalem与之前的架构有很大不同)。6系列测试仅影响是否显示错误消息;它的作用只是错误消息仅显示在Intel CPU上,而不显示在AMD CPU上(Intel家族6自Pentium Pro起包括所有非NetBurst Intel CPU)。

要回答您的配置问题,您可以完全禁用intel_idle,但是也可以将其保留(只要您不介意警告)。


pr_debug()消息仅在您执行了非常特定的操作以启用该调试消息时才出现,因此您甚至不必忽略警告
sourcejedi

2
@sourcejedi我提到那是因为OP正在看到它。
史蒂芬·基特

知道了。我提出了一个严肃的评论:由于我们被问到一个合理的内核配置,如果每天都使用它,也许不使用启用所有调试消息的选项?使用正确的选项,可以在必要时动态地和有选择地启用它们。kernel.org/doc/html/v4.17/admin-guide/dynamic-debug-howto.html 如果启用所有调试消息,则可能会有很多消息仍然被您忽略:)。
sourcejedi

@sourcejedi我看不到您有关禁用内核消息的评论的相关性。我不认为这对问题有建设性,该问题专门解决了对intel_idle驱动程序的Core 2支持。
vallismortis

@vallismortis非常切线。这意味着您可以为Core 2 及更高版本使用有效的配置,该配置不会将其显示为令人讨厌的警告消息,必须将其简单地忽略掉,如果支持,它将使用intel_idle ...但是我想您会使用动态加载无论如何,模块,所以也许不值得一提。
sourcejedi

6

是否有更合适的方法来配置内核,以为此处理器系列提供最佳的CPU空闲支持(除了禁用对intel_idle的支持之外)

您已启用ACPI,并且已检查acpi_idle是否正在使用。我衷心怀疑您是否错过了任何有用的内核配置选项。您可以随时检查powertop可能的建议,但是您可能已经知道了。


这不是一个答案,但我想将其格式化:-(。

查看内核源代码,当前的intel_idle驱动程序包含一个测试,专门用于从驱动程序中排除Intel家族6。

不,它不是:-)。

id = x86_match_cpu(intel_idle_ids);
if (!id) {
    if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
        boot_cpu_data.x86 == 6)
        pr_debug(PREFIX "does not run on family %d model %d\n",
            boot_cpu_data.x86, boot_cpu_data.x86_model);
    return -ENODEV;
}

if语句不排除家族6。相反,该if语句在启用调试时提供一条消息,表明该特定的现代Intel CPU不支持intel_idle。实际上,我当前的i5-5300U CPU是Family 6,它使用intel_idle

排除您的CPU的是intel_idle_ids表中没有匹配项。

我注意到此提交实现了表。它删除的代码switch改为有一条语句。这很容易看出最早的模型intel_idle已经实现/成功测试/无论是0x1A =26。https: //github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.