Estou ajustando meu kernel Linux para processadores Intel Core 2 Quad (Yorkfield) e notei as seguintes mensagens 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
O PowerTop mostra apenas os estados C1, C2 e C3 sendo usados para o pacote e os núcleos individuais:
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, consultei sysfs
e descobri que o driver legado acpi_idle
estava em uso (esperava ver o intel_idle
driver):
cat /sys/devices/system/cpu/cpuidle/current_driver
acpi_idle
Observando o código-fonte do kernel, o driver intel_idle atual contém uma mensagem de depuração observando especificamente que alguns modelos da família 6 da Intel não são suportados pelo driver:
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);
Um fork anterior (22 de novembro de 2010) do intel_idle.c mostra suporte antecipado para processadores Core 2 (o modelo 23 na verdade cobre tanto o Core 2 Duo quanto o Quad):
#ifdef FUTURE_USE
case 0x17: /* 23 - Core 2 Duo */
lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
#endif
O código acima foi deletado no commit de dezembro de 2010 .
Infelizmente, quase não há documentação no código-fonte, portanto não há explicação sobre a falta de suporte para a função ociosa nessas CPUs.
Minha configuração atual do kernel é a seguinte:
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
Minha pergunta é a seguinte:
- Existe um motivo específico de hardware pelo qual os processadores Core 2 não são suportados
intel_idle
? - Existe uma maneira mais apropriada de configurar um kernel para suporte ocioso de CPU ideal para esta família de processadores (além de desabilitar o suporte para
intel_idle
)?
Enquanto pesquisava os estados de energia da CPU Core 2 (" C-states "), consegui implementar suporte para a maioria dos processadores Intel Core/Core 2 legados. A implementação completa (patch Linux) com todas as informações básicas está documentada aqui.
À medida que acumulava mais informações sobre esses processadores, começou a ficar evidente que os estados C suportados no(s) modelo(s) Core 2 são muito mais complexos do que os dos processadores anteriores e posteriores. Estes são conhecidos como estados C aprimorados (ou " CxE "), que envolvem o pacote, núcleos individuais e outros componentes no chipset (por exemplo, memória). Na época em que o
intel_idle
driver foi lançado, o código não era particularmente maduro e vários processadores Core 2 foram lançados com suporte C-state conflitante.Algumas informações interessantes sobre o suporte do Core 2 Solo/Duo C-state foram encontradas neste artigo de 2006 . Isso é em relação ao suporte no Windows, no entanto, indica o suporte robusto de hardware C-state nesses processadores. As informações sobre Kentsfield entram em conflito com o número do modelo real, então acredito que eles estejam se referindo a um Yorkfield abaixo:
Este artigo de 2008 descreve o suporte para estados C por núcleo em processadores Intel de vários núcleos, incluindo Core 2 Duo e Core 2 Quad (leitura adicional útil em segundo plano foi encontrada neste white paper da Dell ):
Encontrei uma apresentação de 2010 da Intel que fornece informações adicionais sobre o
intel_idle
driver, mas infelizmente não explica a falta de suporte ao Core 2:A apresentação acima indica que o
intel_idle
driver é uma implementação do controlador de CPU "menu", que tem um impacto na configuração do kernel Linux (ou seja,CONFIG_CPU_IDLE_GOV_LADDER
vs.CONFIG_CPU_IDLE_GOV_MENU
). As diferenças entre os reguladores de escada e de menu são descritas sucintamente nesta resposta .A Dell tem um artigo útil que lista a compatibilidade de C-state C0 a C6:
A partir desta tabela (que mais tarde descobri estar incorreta em alguns casos), parece que havia uma variedade de diferenças no suporte ao estado C com os processadores Core 2 (Observe que quase todos os processadores Core 2 são Socket LGA775, exceto Core 2 Solo SU3500, que é Socket BGA956 e processadores Merom/Penryn. Os processadores "Intel Core" Solo/Duo são um dos Socket PBGA479 ou PPGA478).
Uma exceção adicional à tabela foi encontrada neste artigo :
Curiosamente, o QX9650 é um processador Yorkfield (família Intel 6, modelo 23, passo 6). Para referência, meu Q9550S é a família Intel 6, modelo 23 (0x17), passo 10, que supostamente suporta C-state C4 (confirmado através de experimentação). Além disso, o Core 2 Solo U3500 tem um CPUID idêntico (família, modelo, stepping) ao Q9550S, mas está disponível em um soquete não LGA775, o que confunde a interpretação da tabela acima.
Claramente, o CPUID deve ser usado pelo menos até o stepping para identificar o suporte de estado C para este modelo de processador e, em alguns casos, pode ser insuficiente (indeterminado neste momento).
A assinatura do método para atribuir informações ociosas da CPU é:
Onde
model
é enumerado em asm/intel-family.h . Examinando este arquivo de cabeçalho, vejo que os processadores Intel recebem identificadores de 8 bits que parecem corresponder aos números de modelo da família Intel 6:Do acima, temos Intel Family 6, Model 23 (0x17) definido como
INTEL_FAM6_CORE2_PENRYN
. Isso deve ser suficiente para definir estados ociosos para a maioria dos processadores Modelo 23, mas pode causar problemas com o QX9650, conforme observado acima.Assim, minimamente, cada grupo de processadores que possui um conjunto de estados C distinto precisaria ser definido nesta lista.
Zagacki e Ponnala, Intel Technology Journal 12 (3):219-227, 2008 indicam que os processadores Yorkfield de fato suportam C2 e C4. Eles também parecem indicar que a especificação ACPI 3.0a suporta transições apenas entre os estados C C0, C1, C2 e C3, o que presumo que também pode limitar o
acpi_idle
driver Linux a transições entre esse conjunto limitado de estados C. No entanto, este artigo indica que nem sempre pode ser o caso:Também digno de nota:
O chipset que estou usando é de fato um chipset Intel Q45 Express.
A documentação da Intel sobre os estados do MWAIT é concisa, mas confirma o comportamento ACPI específico do BIOS:
Minha interpretação da tabela acima (combinada com uma tabela da Wikipedia , asm/intel-family.h e os artigos acima) é:
Modelo 9 0x09 ( Pentium M e Celeron M ):
Modelo 13 0x0D ( Pentium M e Celeron M ):
Modelo 14 0x0E INTEL_FAM6_CORE_YONAH ( Pentium M aprimorado , Celeron M aprimorado ou Intel Core ):
Modelo 15 0x0F INTEL_FAM6_CORE2_MEROM (alguns Core 2 e Pentium Dual-Core ):
Modelo 23 0x17 INTEL_FAM6_CORE2_PENRYN ( Núcleo 2 ):
A partir da quantidade de diversidade no suporte C-state apenas na linha de processadores Core 2, parece que a falta de suporte consistente para C-states pode ter sido a razão para não tentar suportá-los totalmente por meio do
intel_idle
driver. Eu gostaria de completar totalmente a lista acima para toda a linha Core 2.Esta não é realmente uma resposta satisfatória, porque me faz pensar quanta energia desnecessária é usada e o excesso de calor foi (e ainda é) gerado por não utilizar totalmente os robustos estados C MWAIT de economia de energia nesses processadores.
Chattopadhyay et al. 2018, Processadores de alto desempenho com eficiência energética: abordagens recentes para projetar computação de alto desempenho verde vale a pena notar para o comportamento específico que estou procurando no chipset Q45 Express:
Como teste, inseri o seguinte em linux/drivers/idle/intel_idle.c linha 127:
na
intel_idle.c
linha 983:na
intel_idle.c
linha 1073:Após uma rápida compilação e reinicialização dos meus nós PXE,
dmesg
agora mostra:E agora o PowerTOP está mostrando:
I've finally accessed the Enhanced Core 2 C-states, and it looks like there is a measurable drop in power consumption - my meter on 8 nodes appears to be averaging at least 5% lower (with one node still running the old kernel), but I'll try swapping the kernels out again as a test.
An interesting note regarding C4E support - My Yorktown Q9550S processor appears to support it (or some other sub-state of C4), as evidenced above! This confuses me, because the Intel datasheet on the Core 2 Q9000 processor (section 6.2) only mentions C-states Normal (C0), HALT (C1 = 0x00), Extended HALT (C1E = 0x01), Stop Grant (C2 = 0x10), Extended Stop Grant (C2E = 0x11), Sleep/Deep Sleep (C3 = 0x20) and Deeper Sleep (C4 = 0x30). What is this additional 0x31 state? If I enable state C2, then C4E is used instead of C4. If I disable state C2 (force state C2E) then C4 is used instead of C4E. I suspect this may have something to do with the MWAIT flags, but I haven't yet found documentation for this behavior.
I'm not certain what to make of this: The C1E state appears to be used in lieu of C1, C2 is used in lieu of C2E and C4E is used in lieu of C4. I'm uncertain if C1/C1E, C2/C2E and C4/C4E can be used together with
intel_idle
or if they are redundant. I found a note in this 2010 presentation by Intel Labs Pittsburgh that indicates the transitions are C0 - C1 - C0 - C1E - C0, and further states:I believe that is to be interpreted as the C1E state is entered on other components (e.g. memory) only when all cores are in the C1E state. I also take this to apply equivalently to the C2/C2E and C4/C4E states (Although C4E is referred to as "C4E/C5" so I'm uncertain if C4E is a sub-state of C4 or if C5 is a sub-state of C4E. Testing seems to indicate C4/C4E is correct). I can force C2E to be used by commenting out the C2 state - however, this causes the C4 state to be used instead of C4E (more work may be required here). Hopefully there aren't any model 15 or model 23 processors that lack state C2E, because those processors would be limited to C1/C1E with the above code.
Also, the flags, latency and residency values could probably stand to be fine-tuned, but just taking educated guesses based on the Nehalem idle values seems to work fine. More reading will be required to make any improvements.
I tested this on a Core 2 Duo E2220 (Allendale), a Dual Core Pentium E5300 (Wolfdale), Core 2 Duo E7400, Core 2 Duo E8400 (Wolfdale), Core 2 Quad Q9550S (Yorkfield) and Core 2 Extreme QX9650, and I have found no issues beyond the afore-mentioned preference for state C2/C2E and C4/C4E.
Not covered by this driver modification:
The only issues that I can think of are:
intel_idle
driver appears to choose the appropriate C1/C1E based on hardware support of the sub-states.I managed to find a slide from a 2009 Intel presentation on the transitions between C-states (i.e., Deep Power Down):
In conclusion, it turns out that there was no real reason for the lack of Core 2 support in the
intel_idle
driver. It is clear now that the original stub code for "Core 2 Duo" only handled C-states C1 and C2, which would have been far less efficient than theacpi_idle
function which also handles C-state C3. Once I knew where to look, implementing support was easy. The helpful comments and other answers were much appreciated, and if Amazon is listening, you know where to send the check.This update has been committed to github. I will e-mail a patch to the LKML soon.
Update: I also managed to dig up a Socket T/LGA775 Allendale (Conroe) Core 2 Duo E2220, which is family 6, model 15, so I added support for that as well. This model lacks support for C-state C4, but supports C1/C1E and C2/C2E. This should also work for other Conroe-based chips (E4xxx/E6xxx) and possibly all Kentsfield and Merom (non Merom-L) processors.
Update: I finally found some MWAIT tuning resources. This Power vs. Performance writeup and this Deeper C states and increased latency blog post both contain some useful information on identifying CPU idle latencies. Unfortunately, this only reports those exit latencies that were coded into the kernel (but, interestingly, only those hardware states supported by the processor):
Update: An Intel employee recently published an article on
intel_idle
detailing MWAIT states.Você ativou a ACPI e verificou se acpi_idle está em uso. Eu sinceramente duvido que você tenha perdido alguma opção útil de configuração do kernel. Você sempre pode verificar
powertop
possíveis sugestões, mas provavelmente você já sabia disso.Esta não é uma resposta, mas quero formatá-la :-(.
Não, não :-).
A
if
instrução não exclui a Família 6. Em vez disso, aif
instrução fornece uma mensagem quando a depuração está habilitada, informando que essa CPU Intel moderna específica não é suportada pelointel_idle
. Na verdade, minha CPU i5-5300U atual é a Família 6 e usaintel_idle
.O que exclui sua CPU é que não há correspondência na
intel_idle_ids
tabela.Eu notei este commit que implementou a tabela. O código que ele remove tinha uma
switch
instrução em vez disso. Isso facilita ver que o modelo mais antigo intel_idle foi implementado/testado com sucesso/qualquer que seja 0x1A = 26. https://github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186Eu suspeito que este poderia ser apenas um caso de oportunidade e custo. Quando
intel_idle
foi adicionado, parece que o suporte ao Core 2 Duo foi planejado, mas nunca foi totalmente implementado - talvez quando os engenheiros da Intel chegaram a ele, não valeu mais a pena. A equação é relativamente complexa:intel_idle
precisa fornecer benefícios suficientesacpi_idle
para valer a pena suportar aqui, em CPUs que verão o kernel “melhorado” em número suficiente ...Como a resposta do sourcejedi diz, o driver não exclui toda a família 6. A inicialização verifica CPUs em uma lista de modelos de CPU , cobrindo basicamente todas as microarquiteturas de Nehalem a Kaby Lake. Yorkfield é mais antigo do que isso (e significativamente diferente - Nehalem é muito diferente das arquiteturas que vieram antes dele). O teste da família 6 afeta apenas se a mensagem de erro é impressa; seu efeito é apenas que a mensagem de erro será exibida apenas em CPUs Intel, não em CPUs AMD (a família Intel 6 inclui todas as CPUs Intel não NetBurst desde o Pentium Pro).
intel_idle
Para responder à sua pergunta de configuração, você pode desabilitar completamente
intel_idle
, mas deixá-lo também está bem (contanto que você não se importe com o aviso).Another year, less and less of these old machines, but still no kernel support for idle states. I customised a kernel in a similar way to above and got useful drops in core temperature and power use. Previously the core temperatures were around 60C at idle, and around 45C with the custom intel_idle.
I used a slightly different configuration in intel_idle.c. I set the disable C1E promotion flag: C1E is a state that is normally reached automatically (if configured in the BIOS) whenever a processor is put into C1. intel_idle disables this in all cases and treats C1E as a separate C-state, mainly to avoid the processor dropping unexpectedly into a state with a latency that could cause QoS issues (note that this means max_cstate is one higher than you might expect because 2 is C1E). The C2E state is similar, but not disabled or handled separately in intel_idle, so I left it out of the configuration completely. The BIOS usually has an option to enable or disable automatic promotion to this state, so you could disable it in the BIOS, enable it in intel_idle, and possibly get better results but I haven't tried it.
This was on an E2180, so no states higher than C2/C2E, but the main gains seem to come with the first idle state. I have an even older Pentium 4 with Linux support only for C1 and that knocks 10-15C off the core temperature. Experiments with a Core i7 show only marginal extra temperature drops with enabling C3 or C6, although you might think that battery savings are still worth it. I haven't found any noticeable performance issues with the latencies configured as shown above, but it isn't exactly a hardcore gaming machine anyway.