¿Por qué algunos modelos de CPU de la familia Intel 6 (Core 2, Pentium M) no son compatibles con intel_idle?


25

He estado ajustando mi kernel de Linux para procesadores Intel Core 2 Quad (Yorkfield), y noté los siguientes mensajes de 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 muestra solo los estados C1, C2 y C3 que se utilizan para el paquete y los núcleos individuales:

          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

Curioso, pregunté sysfsy descubrí que el acpi_idlecontrolador heredado estaba en uso (esperaba ver el intel_idlecontrolador):

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

acpi_idle

Mirando el código fuente del kernel, el controlador intel_idle actual contiene un mensaje de depuración que señala específicamente que algunos modelos de la familia Intel 6 no son compatibles con el controlador:

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);

Una bifurcación anterior (22 de noviembre de 2010) de intel_idle.c muestra el soporte anticipado para los procesadores Core 2 (el modelo 23 en realidad cubre Core 2 Duo y Quad):

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

El código anterior se eliminó en commit de diciembre de 2010 .

Desafortunadamente, casi no hay documentación en el código fuente, por lo que no hay explicación sobre la falta de soporte para la función inactiva en estas CPU.

Mi configuración actual del kernel es la siguiente:

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

Mi pregunta es la siguiente:

  • ¿Hay alguna razón de hardware específica por la cual los procesadores Core 2 no sean compatibles intel_idle?
  • ¿Existe una forma más adecuada de configurar un núcleo para un soporte inactivo de CPU óptimo para esta familia de procesadores (aparte de deshabilitar el soporte para intel_idle)?

Respuestas:


28

Mientras investigaba los estados de potencia de la CPU Core 2 (" C "), logré implementar el soporte para la mayoría de los procesadores Intel Core / Core 2 heredados. Aquí se documenta la implementación completa (parche de Linux) con toda la información de fondo.

A medida que acumulé más información sobre estos procesadores, comenzó a hacerse evidente que los estados C admitidos en los modelos Core 2 son mucho más complejos que los procesadores anteriores y posteriores. Estos se conocen como estados C mejorados (o " CxE "), que involucran el paquete, los núcleos individuales y otros componentes en el conjunto de chips (p. Ej., Memoria). En el momento en intel_idleque se lanzó el controlador, el código no era particularmente maduro y se habían lanzado varios procesadores Core 2 que tenían un soporte de estado C en conflicto.

En este artículo de 2006 se encontró información convincente sobre el soporte Core 2 Solo / Duo C-state . Esto está relacionado con el soporte en Windows, sin embargo, sí indica el soporte robusto del estado C del hardware en estos procesadores. La información sobre Kentsfield entra en conflicto con el número de modelo real, por lo que creo que en realidad se refieren a un Yorkfield a continuación:

... el procesador de cuatro núcleos Intel Core 2 Extreme (Kentsfield) admite las cinco tecnologías de rendimiento y ahorro de energía: Intel SpeedStep (EIST) mejorado, Monitor térmico 1 (TM1) y Monitor térmico 2 (TM2), antiguo reloj bajo demanda Modulación (ODCM), así como Estados C mejorados (CxE). En comparación con los procesadores Intel Pentium 4 y Pentium D 600, 800 y 900, que se caracterizan solo por el estado de detención mejorada (C1), esta función se ha ampliado en los procesadores Intel Core 2 (así como en los procesadores Intel Core Solo / Duo) para todos los posibles estados inactivos de un procesador, incluidos Stop Grant (C2), Deep Sleep (C3) y Deeper Sleep (C4).

Este artículo de 2008 describe el soporte para estados C por núcleo en procesadores Intel de múltiples núcleos, incluidos Core 2 Duo y Core 2 Quad (se encontró una lectura de fondo útil adicional en este documento de Dell ):

Un estado C central es un estado C de hardware. Hay varios estados inactivos centrales, por ejemplo, CC1 y CC3. Como sabemos, un procesador moderno de última generación tiene múltiples núcleos, como los procesadores móviles Core Duo T5000 / T7000 recientemente lanzados, conocidos como Penryn en algunos círculos. Lo que solíamos pensar como una CPU / procesador, en realidad tiene múltiples CPU de propósito general a su lado. El Intel Core Duo tiene 2 núcleos en el chip del procesador. El Intel Core-2 Quad tiene 4 de estos núcleos por chip de procesador. Cada uno de estos núcleos tiene su propio estado inactivo. Esto tiene sentido ya que un núcleo puede estar inactivo mientras otro está trabajando duro en un hilo. Entonces, un estado C central es el estado inactivo de uno de esos núcleos.

Encontré una presentación de 2010 de Intel que proporciona algunos antecedentes adicionales sobre el intel_idlecontrolador, pero desafortunadamente no explica la falta de soporte para Core 2:

Este controlador EXPERIMENTAL sustituye a acpi_idle en los procesadores Intel Atom, los procesadores Intel Core i3 / i5 / i7 y los procesadores Intel Xeon asociados. No es compatible con el procesador Intel Core2 o anterior.

La presentación anterior indica que el intel_idlecontrolador es una implementación del gobernador de CPU del "menú", que tiene un impacto en la configuración del kernel de Linux (es decir, CONFIG_CPU_IDLE_GOV_LADDERvs. CONFIG_CPU_IDLE_GOV_MENU). Las diferencias entre los gobernadores de escalera y de menú se describen sucintamente en esta respuesta .

Dell tiene un útil artículo que enumera la compatibilidad C-state C0 a C6:

Los modos C1 a C3 funcionan básicamente cortando las señales de reloj utilizadas dentro de la CPU, mientras que los modos C4 a C6 funcionan reduciendo el voltaje de la CPU. Los modos "mejorado" pueden hacer ambas cosas al mismo tiempo.

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

De esta tabla (que luego descubrí que era incorrecta en algunos casos), parece que hubo una variedad de diferencias en el soporte de estado C con los procesadores Core 2 (tenga en cuenta que casi todos los procesadores Core 2 son Socket LGA775, excepto Core 2 Solo SU3500, que son procesadores Socket BGA956 y Merom / Penryn. Los procesadores "Intel Core" Solo / Duo son uno de los Socket PBGA479 o PPGA478).

Se encontró una excepción adicional a la tabla en este artículo :

El Core 2 Duo E8500 de Intel es compatible con los estados C C2 y C4, mientras que el Core 2 Extreme QX9650 no.

Curiosamente, el QX9650 es un procesador Yorkfield (Intel familia 6, modelo 23, paso 6). Como referencia, mi Q9550S ​​es la familia Intel 6, modelo 23 (0x17), paso 10, que supuestamente admite C-state C4 (confirmado mediante experimentación). Además, el Core 2 Solo U3500 tiene un CPUID idéntico (familia, modelo, paso a paso) al Q9550S, pero está disponible en un zócalo no LGA775, lo que confunde la interpretación de la tabla anterior.

Claramente, el CPUID debe usarse al menos hasta el escalón para identificar el soporte de estado C para este modelo de procesador, y en algunos casos puede ser insuficiente (indeterminado en este momento).

La firma del método para asignar información inactiva de la CPU es:

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

Donde modelse enumera en asm / intel-family.h . Al examinar este archivo de encabezado, veo que a las CPU Intel se les asignan identificadores de 8 bits que parecen coincidir con los números de modelo de la familia Intel 6:

#define INTEL_FAM6_CORE2_PENRYN 0x17

De lo anterior, tenemos Intel Family 6, Modelo 23 (0x17) definido como INTEL_FAM6_CORE2_PENRYN . Esto debería ser suficiente para definir estados inactivos para la mayoría de los procesadores Modelo 23, pero podría causar problemas con QX9650 como se indicó anteriormente.

Por lo tanto, como mínimo, cada grupo de procesadores que tenga un conjunto de estados C distinto debería definirse en esta lista.

Zagacki y Ponnala, Intel Technology Journal 12 (3): 219-227, 2008 indican que los procesadores Yorkfield sí admiten C2 y C4. También parecen indicar que la especificación ACPI 3.0a admite transiciones solo entre los estados C C0, C1, C2 y C3, lo que supongo que también puede limitar el acpi_idlecontrolador de Linux a las transiciones entre ese conjunto limitado de estados C. Sin embargo, este artículo indica que puede no ser siempre el caso:

Tenga en cuenta que es el estado ACPI C, no el procesador, por lo que ACPI C3 podría ser HW C6, etc.

También de nota:

Más allá del procesador en sí, dado que C4 es un esfuerzo sincronizado entre los principales componentes de silicio en la plataforma, el chipset Intel Q45 Express logra una mejora de energía del 28 por ciento.

El chipset que estoy usando es un chipset Intel Q45 Express.

La documentación de Intel sobre los estados MWAIT es breve pero confirma el comportamiento ACPI específico del BIOS:

Los estados C específicos del procesador definidos en las extensiones MWAIT pueden correlacionarse con los tipos de estado C definidos por ACPI (C0, C1, C2, C3). La relación de mapeo depende de la definición de un estado C por implementación del procesador y el BIOS la expone a OSPM utilizando la tabla _CST definida por ACPI.

Mi interpretación de la tabla anterior (combinada con una tabla de Wikipedia , asm / intel-family.h y los artículos anteriores) es:

Modelo 9 0x09 ( Pentium M y Celeron M ):

  • Banias: C0, C1, C2, C3, C4

Modelo 13 0x0D ( Pentium M y Celeron M ):

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

Modelo 14 0x0E INTEL_FAM6_CORE_YONAH ( Pentium M mejorado , Celeron M mejorado o Intel Core ):

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

Modelo 15 0x0F INTEL_FAM6_CORE2_MEROM (algunos Core 2 y Pentium Dual-Core ):

  • Kentsfield, Merom, Conroe, Allendale ( E2xxx / E4xxx y Core 2 Duo E6xxx, T7xxxx / T8xxxx , Core 2 Extreme QX6xxx , Core 2 Quad Q6xxx ): C0, C1, C1E, C2, C2E

Modelo 23 0x17 INTEL_FAM6_CORE2_PENRYN ( Core 2 ):

  • Merom-L / Penryn-L:?
  • Penryn ( Core 2 Duo 45-nm mobile ): C0, C1, C1E, C2, C2E, C3, C4, C4E / C5, C6
  • Yorkfield ( Core 2 Extreme QX9650 ): C0, C1, C1E, C2E ?, C3
  • Wolfdale / Yorkfield ( Core 2 Quad , C2Q Xeon , Core 2 Duo E5xxx / E7xxx / E8xxx , Pentium Dual-Core E6xxx , Celeron Dual-Core ): C0, C1, C1E, C2, C2E, C3, C4

Por la cantidad de diversidad en el soporte de estado C dentro de solo la línea de procesadores Core 2, parece que la falta de soporte consistente para los estados C puede haber sido la razón para no intentar apoyarlos completamente a través del intel_idle controlador. Me gustaría completar completamente la lista anterior para toda la línea Core 2.

Esta no es realmente una respuesta satisfactoria, porque me hace preguntarme cuánta energía innecesaria se usa y se ha generado (y aún se genera) un exceso de calor al no utilizar completamente los robustos estados C MWAIT de ahorro de energía en estos procesadores.

Chattopadhyay y col. 2018, Procesadores energéticamente eficientes de alto rendimiento: enfoques recientes para el diseño de la informática ecológica de alto rendimiento vale la pena señalar el comportamiento específico que estoy buscando en el chipset Q45 Express:

Paquete C-estado (PC0-PC10): cuando los dominios de proceso, Core y Graphics (GPU) están inactivos, el procesador tiene la oportunidad de ahorrar energía adicional a niveles de núcleo y plataforma, por ejemplo, vaciar la LLC y activar el controlador de memoria y DRAM IO, y en algún estado, todo el procesador puede apagarse mientras su estado se mantiene en el dominio de energía siempre encendido.

Como prueba, inserté lo siguiente en linux / drivers / idle / intel_idle.c línea 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 }
};

en la intel_idle.clínea 983:

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,
};

en la intel_idle.clínea 1073:

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

Después de una rápida compilación y reinicio de mis nodos PXE, dmesgahora muestra:

[    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

Y ahora PowerTOP está mostrando:

          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

Finalmente he accedido a los estados C mejorados de Core 2, y parece que hay una caída medible en el consumo de energía: mi medidor en 8 nodos parece estar promediando al menos un 5% menos (con un nodo que todavía ejecuta el núcleo antiguo) , pero intentaré cambiar los núcleos nuevamente como prueba.

Una nota interesante con respecto al soporte C4E: mi procesador Q9550S ​​de Yorktown parece admitirlo (o algún otro subestado de C4), como se evidencia anteriormente. Esto me confunde, porque la hoja de datos de Intel en el procesador Core 2 Q9000 (sección 6.2) solo menciona los estados C Normal (C0), HALT (C1 = 0x00), Extended HALT (C1E = 0x01), Stop Grant (C2 = 0x10) , Grant Stop extendido (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) y Deeper Sleep (C4 = 0x30). ¿Cuál es este estado adicional 0x31? Si habilito el estado C2, entonces se usa C4E en lugar de C4. Si desactivo el estado C2 (estado de fuerza C2E), entonces se usa C4 en lugar de C4E. Sospecho que esto puede tener algo que ver con las banderas MWAIT, pero todavía no he encontrado documentación para este comportamiento.

No estoy seguro de qué hacer con esto: el estado C1E parece usarse en lugar de C1, C2 se usa en lugar de C2E y C4E se usa en lugar de C4. No estoy seguro si C1 / C1E, C2 / C2E y C4 / C4E se pueden usar junto con intel_idleo si son redundantes. Encontré una nota en esta presentación de 2010 de Intel Labs Pittsburgh que indica que las transiciones son C0 - C1 - C0 - C1E - C0, y otros estados:

C1E solo se usa cuando todos los núcleos están en C1E

Creo que debe interpretarse como el estado C1E se ingresa en otros componentes (por ejemplo, memoria) solo cuando todos los núcleos están en el estado C1E. También considero que esto se aplica de manera equivalente a los estados C2 / C2E y C4 / C4E (aunque C4E se conoce como "C4E / C5", así que no estoy seguro si C4E es un subestado de C4 o si C5 es un sub- estado de C4E. Las pruebas parecen indicar que C4 / C4E es correcto). Puedo forzar el uso de C2E comentando el estado de C2; ​​sin embargo, esto hace que se use el estado de C4 en lugar de C4E (es posible que se requiera más trabajo aquí). Esperemos que no haya ningún procesador modelo 15 o modelo 23 que carezca del estado C2E, porque esos procesadores estarían limitados a C1 / C1E con el código anterior.

Además, los valores de las banderas, la latencia y la residencia probablemente podrían ajustarse, pero solo tomar conjeturas fundamentadas basadas en los valores inactivos de Nehalem parece funcionar bien. Se requerirá más lectura para hacer cualquier mejora.

Probé esto en un Core 2 Duo E2220 ( Allendale ), un Dual Core Pentium E5300 ( Wolfdale ), Core 2 Duo E7400 , Core 2 Duo E8400 ( Wolfdale ), Core 2 Quad Q9550S ( Yorkfield ) y Core 2 Extreme QX9650 , y yo No hemos encontrado problemas más allá de la preferencia mencionada anteriormente para el estado C2 / C2E y C4 / C4E.

No cubierto por esta modificación del controlador:

  • Los Core Solo / Core Duo originales ( Yonah , no Core 2) son de la familia 6, modelo 14. Esto es bueno porque admitían los estados C C4E / C5 (sueño profundo mejorado) pero no los estados C1E / C2E y necesitarían su propia definición de inactividad.

Los únicos problemas que puedo pensar son:

  • Core 2 Solo SU3300 / SU3500 (Penryn-L) son de la familia 6, modelo 23 y serán detectados por este controlador. Sin embargo, no son Socket LGA775, por lo que es posible que no admitan el estado C de detención mejorada de C1E. Del mismo modo para el Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Sin embargo, el intel_idlecontrolador parece elegir el C1 / C1E apropiado en función del soporte de hardware de los subestados.
  • Según se informa, Core 2 Extreme QX9650 (Yorkfield) no es compatible con C-state C2 o C4. He confirmado esto comprando un procesador Optiplex 780 y QX9650 Extreme usado en eBay. El procesador admite los estados C C1 y C1E. Con esta modificación del controlador, la CPU está inactiva en el estado C1E en lugar de C1, por lo que presumiblemente hay algunos ahorros de energía. Esperaba ver C-state C3, pero no está presente cuando uso este controlador, por lo que es posible que deba investigar esto más a fondo.

Logré encontrar una diapositiva de una presentación de Intel de 2009 sobre las transiciones entre estados C (es decir, Deep Power Down):

Entrada / salida de tecnología de apagado profundo

En conclusión, resulta que no había una razón real para la falta de compatibilidad con Core 2 en el intel_idlecontrolador. Ahora está claro que el código auxiliar original para "Core 2 Duo" solo maneja los estados C C1 y C2, que habrían sido mucho menos eficientes que la acpi_idlefunción que también maneja el estado C C3. Una vez que supe dónde buscar, implementar el soporte fue fácil. Los comentarios útiles y otras respuestas fueron muy apreciados, y si Amazon está escuchando, ya sabe dónde enviar el cheque.

Esta actualización se ha comprometido con github . Enviaré un parche por correo electrónico a LKML pronto.

Actualización : También logré desenterrar un Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, que es la familia 6, modelo 15, por lo que también agregué soporte para eso. Este modelo carece de soporte para C-state C4, pero admite C1 / C1E y C2 / C2E. Esto también debería funcionar para otros chips basados ​​en Conroe ( E4xxx / E6xxx ) y posiblemente para todos los procesadores Kentsfield y Merom (no Merom-L).

Actualización : finalmente encontré algunos recursos de ajuste de MWAIT. Esta redacción de Power vs. Performance y estos estados de C más profundos y la publicación de blog de latencia aumentada contienen información útil sobre la identificación de latencias inactivas de CPU. Desafortunadamente, esto solo informa las latencias de salida que se codificaron en el núcleo (pero, curiosamente, solo los estados de hardware admitidos por el procesador):

# 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

44
¡Eso es un buen trabajo de detective! Había olvidado lo complejos que eran los estados C C2D / C2Q. Vuelva a aprovechar el ahorro de energía, si su firmware es lo suficientemente bueno, entonces aún debería obtener el beneficio de al menos algunos de los estados C a través de acpi_idle los diversos gobernadores de rendimiento. ¿Qué estados se powertopmuestran en su sistema?
Stephen Kitt

1
Muy buena información, ¿ha considerado proponer su parche al kernel de Linux?
Lekensteyn

1
"El estado C1E parece usarse en lugar de C1 ..." El estado que se usa, como lo muestra Powertop, está determinado únicamente por el núcleo, por lo tanto, creo que no "tendrá algo que ver con los indicadores MWAIT" se elegirá únicamente en función del orden de los estados y la latencia de salida y la residencia objetivo. Dicho esto, me preocuparía un poco dejar los estados en la tabla si no parecen usarse cuando se prueban ... en caso de que esos estados no funcionen realmente como se esperaba, y haya algún otro patrón de carga de trabajo que condujo a ellos están siendo utilizados y el comportamiento inesperado que ocurre
sourcejedi

1
"las transiciones son C0 - C1 - C0 - C1E - C0" - No creo que sea una buena descripción de esa diapositiva. Desde el powertoppunto de vista del núcleo , todas las transiciones son de C0 o de C0. Si no está en C0, no está ejecutando ninguna instrucción, por lo tanto, el núcleo no puede observar ni solicitar ninguna transición entre estados en esa CPU :-). Y como usted dice, el gobernador del "menú" del núcleo puede, por ejemplo, saltar directamente a C1E, sin pasar ningún tiempo en C1 primero.
sourcejedi

1
"simplemente hacer conjeturas fundamentadas basadas en los valores inactivos de Nehalem parece funcionar bien" - tenga en cuenta que esta no es una buena manera de hacer que su parche sea aceptado en sentido ascendente :-P, ya que la latencia de salida no debe subestimarse, de lo contrario creo que lo hará violar PM_QOS_CPU_DMA_LATENCY, que pueden establecer los controladores (¿o el espacio de usuario?)
sourcejedi

6

Sospecho que esto podría ser solo un caso de oportunidad y costo. Cuando intel_idlese agregó, parece que el soporte de Core 2 Duo fue planeado, pero nunca se implementó por completo, tal vez para cuando los ingenieros de Intel se pusieron a ello, ya no valía la pena. La ecuación es relativamente compleja: intel_idlenecesita proporcionar suficientes beneficios acpi_idlepara que valga la pena apoyarla aquí, en CPU que verán el núcleo "mejorado" en números suficientes ...

Como sourcejedi ‘s respuesta dice, el conductor no excluye a toda la familia 6. Los intel_idlecontroles de inicialización para las CPU en una lista de modelos de CPU , que cubre básicamente todos los micro-arquitecturas de Nehalem a Kaby lago. Yorkfield es más antiguo que eso (y significativamente diferente: Nehalem es muy diferente de las arquitecturas anteriores). La prueba de la familia 6 solo afecta si se imprime el mensaje de error; su efecto es solo que el mensaje de error solo se mostrará en las CPU Intel, no en las CPU AMD (la familia Intel 6 incluye todas las CPU Intel que no son NetBurst desde el Pentium Pro).

Para responder a su pregunta de configuración, puede desactivar por completo intel_idle, pero dejarlo también está bien (siempre y cuando no le importe la advertencia).


pr_debug mensaje () sólo debería aparecer si haces algo muy específico para permitir que el mensaje de depuración, por lo que ni siquiera tiene que pasar por alto la advertencia
sourcejedi

2
@sourcejedi Lo mencioné porque el OP lo está viendo.
Stephen Kitt

te tengo Presento un comentario medio serio: dado que se nos pregunta acerca de una configuración de kernel sensata, si se usa día a día, ¿tal vez no use la opción que habilita todos los mensajes de depuración? Con la opción correcta, se pueden habilitar de forma dinámica y selectiva cuando sea necesario. kernel.org/doc/html/v4.17/admin-guide/dynamic-debug-howto.html Si habilita todos los mensajes de depuración, probablemente tenga muchos mensajes que ignora de todos modos :).
sourcejedi

@sourcejedi No veo la relevancia de sus comentarios sobre la desactivación de los mensajes del núcleo. No veo que esto sea constructivo para la pregunta, que aborda específicamente el soporte de Core 2 para el intel_idlecontrolador.
vallismortis

@vallismortis es muy tangencial. Significa que hay una configuración válida que puede usar para Core 2 y superior , que no imprime esto como un mensaje de advertencia molesto que simplemente debe ignorarse, y usará intel_idle si es compatible ... pero supongo que usaría carga dinámica módulos de todos modos, así que tal vez no valga la pena mencionarlo.
sourcejedi

6

¿Existe una forma más adecuada de configurar un núcleo para un soporte inactivo de CPU óptimo para esta familia de procesadores (aparte de deshabilitar el soporte para intel_idle)

Tiene ACPI habilitado y ha comprobado que acpi_idle está en uso. Dudo sinceramente que haya perdido alguna opción útil de configuración del kernel. Siempre puede verificar powertopposibles sugerencias, pero probablemente ya lo sabía.


Esta no es una respuesta, pero quiero formatearla :-(.

Mirando el código fuente del kernel, el controlador intel_idle actual contiene una prueba para excluir específicamente la familia Intel 6 del controlador.

No, no lo hace :-).

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;
}

La ifdeclaración no excluye la Familia 6. En cambio, la ifdeclaración proporciona un mensaje cuando la depuración está habilitada, que esta CPU Intel moderna específica no es compatible intel_idle. De hecho, mi CPU i5-5300U actual es la Familia 6 y utiliza intel_idle.

Lo que excluye su CPU es que no hay coincidencias en la intel_idle_idstabla.

Noté este commit que implementó la tabla. El código que elimina tenía unswitch declaración en su lugar. Esto facilita ver que el primer modelo intel_idle se ha implementado / probado con éxito / lo que sea 0x1A = 26. https://github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.