35 Argumentos do kernel para baixa latência e alto desempenho #
Configurar os argumentos apropriados do kernel é essencial para otimizar o desempenho, alcançar baixa latência e garantir a implantação bem-sucedida de clusters para cargas de trabalho de telecomunicações. Embora alguns parâmetros sejam projetados especificamente para permitir que o kernel de tempo real funcione de forma ideal, esta seção se aplica tanto às configurações de kernel RT quanto às padrão. Além disso, certos argumentos são obrigatórios para que o método de Provisionamento de Rede Direcionado implante com sucesso nós de cluster downstream.
Remova
kthread_cpusao usar o kernel de tempo real do SUSE. Este parâmetro controla em quais CPUs as threads do kernel são criadas. Ele também controla quais CPUs são permitidos para o PID 1 e para o carregamento de módulos do kernel (o auxiliar de espaço do usuário kmod). Este parâmetro não é reconhecido e não tem qualquer efeito.Isole os núcleos da CPU usando
isolcpus,nohz_full,rcu_nocbseirqaffinity. Para uma lista abrangente de técnicas de CPU pinning, consulte o capítulo CPU Pinning on Host (Chapter 36, Fixação de CPU no Host).Adicione as flags
domain,nohz,managed_irqao argumento de kernelisolcpus. Sem nenhuma flag,isolcpusé equivalente a especificar apenas a flagdomain. Isso isola as CPUs especificadas do agendamento, incluindo tarefas do kernel. A flagnohzinterrompe o tick do agendador nas CPUs especificadas (se apenas uma tarefa estiver executável em uma CPU), e a flagmanaged_irqevita o roteamento de interrupções externas (dispositivo) gerenciadas nas CPUs especificadas. Observe que as linhas IRQ de dispositivos NVMe são totalmente gerenciadas pelo kernel e, como consequência, serão roteadas para os núcleos não isolados (housekeeping). Por exemplo, a linha de comando fornecida ao final desta seção resultará em apenas quatro filas (mais uma fila de administração/controle) alocadas no sistema:for I in $(grep nvme0 /proc/interrupts | cut -d ':' -f1); do cat /proc/irq/${I}/effective_affinity_list; done | column 39 0 19 20 39Este comportamento evita qualquer interrupção causada por E/S de disco em qualquer aplicação sensível ao tempo em execução nos núcleos isolados, mas pode exigir atenção e um projeto cuidadoso para cargas de trabalho focadas em armazenamento.
Ajuste os ticks (interrupções de temporizador periódicas do kernel):
skew_tick=1: os ticks podem, às vezes, ocorrer simultaneamente. Em vez de todas as CPUs receberem seu tick de temporizador exatamente no mesmo momento,skew_tick=1faz com que ocorram em momentos ligeiramente deslocados. Isso ajuda a reduzir o jitter do sistema, resultando em tempos de resposta de interrupção mais consistentes e menores (um requisito essencial para aplicações sensíveis à latência).nohz=on: interrompe o tick de temporizador periódico em CPUs ociosas.nohz_full=<cpu-cores>: Interrompe o tick de temporizador periódico em CPUs especificadas que são dedicadas a aplicações de tempo real.
Desative o tratamento de Machine Check Exception (MCE) especificando
mce=off. MCEs são erros de hardware detectados pelo processador e desativá-los pode evitar logs ruidosos.Adicione
nowatchdogpara desativar o watchdog de soft-lockup, que é implementado como um temporizador em execução no contexto de interrupção de hardware do temporizador. Quando ele expira (ou seja, um soft lockup é detectado), ele imprimirá um aviso (no contexto de interrupção de hardware), executando quaisquer alvos de latência. Mesmo que nunca expire, ele entra na lista de temporizadores, aumentando ligeiramente a sobrecarga de cada interrupção de temporizador. Esta opção também desativa o watchdog NMI, para que os NMIs não possam interferir.nmi_watchdog=0desativa o watchdog NMI (Non-Maskable Interrupt). Isso pode ser omitido quandonowatchdogé usado.RCU (Read-Copy-Update) é um mecanismo de kernel que permite acesso simultâneo e sem bloqueio para muitos leitores a dados compartilhados. Um callback RCU, uma função acionada após um 'período extra', garante que todos os leitores anteriores tenham terminado para que os dados antigos possam ser recuperados com segurança. Nós ajustamos o RCU, particularmente para cargas de trabalho sensíveis, para descarregar esses callbacks de CPUs dedicadas (fixadas), evitando que operações do kernel interfiram em tarefas críticas e sensíveis ao tempo.
Especifique as CPUs fixadas em
rcu_nocbspara que os callbacks RCU não sejam executados nelas. Isso ajuda a reduzir o jitter e a latência para as cargas de trabalho de tempo real.rcu_nocb_pollfaz com que as CPUs sem callback façam 'polling' regularmente para verificar se o tratamento de callback é necessário. Isso pode reduzir a sobrecarga de interrupção.rcupdate.rcu_cpu_stall_suppress=1suprime avisos de travamento de CPU RCU, que às vezes podem ser falsos positivos em sistemas de tempo real com carga pesadarcupdate.rcu_expedited=1acelera o período extra para operações RCU, tornando as seções críticas de leitura mais responsivasrcupdate.rcu_normal_after_boot=1Quando usado com rcu_expedited, permite que o RCU reverta para a operação normal (não acelerada) após a inicialização do sistema.rcupdate.rcu_task_stall_timeout=0desativa o detector de travamento de tarefas RCU, evitando possíveis avisos ou paradas do sistema devido a tarefas RCU de longa duração.rcutree.kthread_prio=99define a prioridade da thread do kernel de callback RCU para a mais alta possível (99), garantindo que ela seja agendada e processe os callbacks RCU prontamente, quando necessário.
Adicione
ignition.platform.id=openstackpara que o Metal3 e a API de Cluster provisionem/desprovisionem o cluster com sucesso. Isso é usado pelo agente Python do Metal3, que se originou do Openstack Ironic.Habilite Nomeação previsível de interface de rede via
net.ifnames=1. A partir do SUSE Linux Micro 6.2, isso é habilitado por padrão e uma configuração explícita não é necessária. Para versões anteriores à 6.2, isso deve ser definido explicitamente como um argumento do kernel. Isso se alinha com a configuraçãopredictableNicNamesno gráfico Helm Metal3 do Cluster de Gerenciamento, que é necessária para que o Provisionamento de Rede Direcionado funcione corretamente. A nomenclatura consistente de interface de rede também é crítica quando o SR-IOV é utilizado.Remova
intel_pstate=passive. Esta opção configuraintel_pstatepara funcionar com governadores cpufreq genéricos, mas para fazer isso funcionar, ela desativa os P-states gerenciados por hardware (HWP) como um efeito colateral. Para reduzir a latência de hardware, esta opção não é recomendada para cargas de trabalho em tempo real.Substitua
intel_idle.max_cstate=0 processor.max_cstate=1poridle=poll. Para evitar transições de C-State, a opçãoidle=pollé usada para desativar as transições de C-State e manter a CPU no C-State mais alto. A opçãointel_idle.max_cstate=0desativaintel_idle, portantoacpi_idleé usada, eacpi_idle.max_cstate=1então define o C-state máximo para acpi_idle. Em arquiteturas AMD64/Intel 64, o primeiro ACPI C-State é semprePOLL, mas ele usa uma funçãopoll_idle(), que pode introduzir uma pequena latência ao ler o clock periodicamente e reiniciar o loop principal emdo_idle()após um tempo limite (isso também envolve limpar e definir a flag de tarefaTIF_POLL). Em contraste,idle=pollexecuta um loop contínuo, aguardando ativamente que uma tarefa seja reagendada. Isso minimiza a latência de saída do estado ocioso, mas ao custo de manter a CPU funcionando em velocidade máxima na thread ociosa.Desative o C1E no BIOS. Esta opção é importante para desativar o estado C1E no BIOS para evitar que a CPU entre no estado C1E quando ociosa. O estado C1E é um estado de baixo consumo de energia que pode introduzir latência quando a CPU está ociosa.
O restante desta documentação aborda parâmetros adicionais, incluindo huge pages e IOMMU.
Isso fornece um exemplo de argumentos de kernel para um servidor Intel de 32 núcleos, incluindo os ajustes mencionados anteriormente:
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=pollAqui está outro exemplo de configuração para um servidor AMD de 64 núcleos. Entre os 128 processadores lógicos (0-127), os primeiros 8 núcleos (0-7) são designados para manutenção, enquanto os 120 núcleos restantes (8-127) são fixados para os aplicativos:
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=575291cf-74e8-42cf-8f2c-408a20dc00b8 skew_tick=1 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 amd_iommu=on iommu=pt irqaffinity=0-7 isolcpus=domain,nohz,managed_irq,8-127 nohz_full=8-127 rcu_nocbs=8-127 mce=off nohz=on nowatchdog nmi_watchdog=0 nosoftlockup quiet rcu_nocb_poll rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll