Como forçar o kernel do Linux a “congelar” (ou quase congelar) por algumas centenas de milissegundos

17

Estamos executando um processo em tempo real em um kernel não em tempo real (CentOS 6), e isso provavelmente não vai mudar.

Temos um aplicativo de streaming de vídeo que requer cerca de 500 MB / s de tráfego PCIe de um FPGA personalizado continuamente por 1,5 horas por vez. O aplicativo funciona muito bem - na maioria das vezes. No entanto, tivemos situações em que parece que o kernel simplesmente parou de responder ao serviço de PCIe ou solicitações de memória por até 500 milissegundos de cada vez. Isso parece acontecer durante o IO do arquivo em rajadas de outro encadeamento. Descobri que é impossível tentar replicar esse problema apenas fazendo muitos arquivos fictícios IO do espaço do usuário enquanto o aplicativo principal está sendo executado.

Existe uma maneira de forçar (simular) um "congelamento" global do kernel do Linux (em particular, parar PCIe ou todos os acessos à memória DDR3 ou algo assim) para que possamos reproduzir esse problema?

Temos um buffer de até 10 milissegundos implementados agora na memória interna do FPGA, mas isso não é suficiente. Podemos armazenar em buffer para FPGA DDR3 e depois descarregar para o host, mas precisamos de um método para testar esse novo recurso sob coação.

Não queremos que o kernel congele ou bloqueie permanentemente. Gostaríamos da possibilidade de definir o intervalo de tempo.

Estou procurando algo como escrever valores mágicos para /proc/sys/vm temporariamente, o que faz com que o sistema rastreie virtualmente e, em seguida, reverta depois de algumas centenas de milissegundos, mas observar o número de maneiras possíveis de quebrá-lo não é para um novato como eu ( link ). Talvez alguns numactl magic?

    
por Mark Lakata 09.10.2014 / 19:58

4 respostas

8

Uma opção para fazer um teste rápido pode ser usar um kernel habilitado para KGDB e parar o kernel manualmente e testar, veja este link .

Em outra nota, coisas que lembro que poderiam causar suas pausas:

  • cpufreq, cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency , o valor está em ns (4000 no meu processador AMD FX (tm) -8120 de oito núcleos) não deve ser um problema, mas verifique
  • Aceleração térmica da própria cpu ou do módulo regulador de tensão.
  • NAPI e / ou tráfego de rede pesado
  • PCIe ASPM ( cat /sys/module/pcie_aspm/parameters/policy )
  • Contenção nos buffers do seu dispositivo de destino (disco rígido, nic ...)
  • Bug no firmware de algum dispositivo no barramento PCIe (mesmo se você não estiver usando), você pode tentar desligá-los com /sys/bus/pci/devices/$DEVICE/power/control
por 15.10.2014 / 14:12
2

Podemos ter mais detalhes sobre como seu aplicativo está se comunicando com o FPGA? É o aplicativo que lê o buffer do FPGA, ou o FPGA que envia uma interrupção para o kernel (como placas de rede)?

Espero que ele abra um bloco / caractere em / dev e se comunique com ele. Isso significa que ele usa um driver para fazer a comunicação entre o aplicativo e o arquivo / dev / XXX.

Eu gostaria de ter a saída de: cat /proc/interrupts ; lsmod ; ls -al /dev/yourmod

Aqui estão as ideias:

  • Se for interrompido, você pode configurar o PIC das CPUs para desabilitar o IRQ correspondente e reativá-lo. Isso fará com que todos os pedidos do cartão sejam ignorados (sem que o cartão esteja ciente disso).
  • se é como um buffer lido, você pode:
    • Coloque seu aplicativo em estado de suspensão, para que os dados do FPGA não sejam lidos e seu buffer seja preenchido, depois acorde seu aplicativo e continue a leitura.
    • Use "crash" ou "kgdb" para alterar o valor "read" para um "noop" por alguns segundos e, em seguida, defina-o de volta para a função padrão.

Por favor, forneça todas as informações que você achar úteis.

    
por 20.10.2014 / 19:45
1

Não tenho certeza se isso ajuda. Mas se você pode escrever um módulo do kernel que chame a função suspend do módulo do kernel de outro dispositivo, isso pode acontecer.

Cada dispositivo PCI pode ser suspenso de acordo com o arquivo de cabeçalho link

Por exemplo, aqui está a função de suspensão da Intel e1000 NIC link

Pelo que me lembro, essa função era usada principalmente quando o sistema entra em hibernação, o driver de dispositivo precisa salvar o status atual de execução e se desligar.

    
por 14.10.2014 / 23:02
0

Eu acho que você está pensando nas linhas erradas. Seu objetivo é claro.

O caminho não é parar o restante dos processos, mas dar aos seus processos principais uma prioridade de sceduling em tempo real. Use nice para seus importantes processos de espaço do usuário para isso.

O problema mais difícil é o tratamento de interrupção PCIe, que reside no espaço do kernel.

Como o hardware está envolvido, você deve começar a dar uma olhada mais de perto na pista PCIe envolvida em sua placa-mãe e como isso é possivelmente conectado a um soquete de CPU específico.

irqbalance normalmente faz um bom trabalho aqui, mas você pode configurar o seu comportamento para atender às suas necessidades.

    
por 18.06.2016 / 09:47