Eu tenho um kernel 2.6.35 PREEMPT em execução no processador ARMv7 de velocidade moderada. Aproximadamente uma vez a cada 100 - 125s, algo faz com que o kernel falhe ao processar alguns drivers relacionados ao áudio com a rapidez necessária para evitar falhas. A espera geralmente varia de 15 a 30 ms, mas pode demorar muito mais. Não está claro se a retenção está totalmente no kernel ou pode estar relacionada ao agendamento de um processo do usuário em execução com prioridade em tempo real (SCHED_RR, 2).
Meu palpite é que existe um (pelo menos um) driver que não está se saindo bem com a preempção.
Alguma saída de rastreio do processo do usuário ilustra algum aspecto do comportamento normal e anormal, embora eu não tenha certeza de como interpretar os vários relatórios de tempo?
Caso normal:
Pesquisa de 0,000518 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3415) = 1 Pesquisa 0.010202 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 Pesquisa 0.000585 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 Pesquisa de 0,000302 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3404) = 1 Pesquisa 0.010706 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3393) = 1 Pesquisa de 0,000480 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3392) = 1
Nenhum bloqueio ocorre na pesquisa de saída no fd6 e, quando apenas o fd10 é pesquisado para entrada, ocorre um bloco de cerca de 10ms. Isso se reflete no relatório da duração da chamada do sistema e no intervalo entre as chamadas do sistema (elas são consistentes).
Caso de falha (exemplo extremo):
Pesquisa de 0,000305 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3543) = 1 Pesquisa 0,010730 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3533) = 1 Pesquisa de 0,000475 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3532) = 1 Pesquisa de 0,000329 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3532) = 1 Pesquisa de 0,953349 ([{fd = 10, eventos = POLLIN | POLLERR | POLLNVAL}, {fd = 6, eventos = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT | POLLERR}], 2, 2578) = 1
Observe neste caso que, embora a segunda última chamada seja gravada em 10 ms (normal), é 953 ms antes da última chamada.
Quais ferramentas posso usar para rastrear o culpado?
Respostas:
perf
pode ser útil para você. Faz parte dos utilitários do kernel do linux.Por exemplo:
Ele mostrará todos os tempos e parâmetros de entrada / saída do syscall (como strace), fornecerá o nome do binário que está chamando o syscall e fará uma amostra da pilha de chamadas de cada CPU em alguma frequência (incluindo símbolos do kernel). Então você pode realmente ver qual código foi executado durante o syscall. Em um sistema multiprocessador, você precisa prestar atenção ao ID da CPU (por exemplo, [001]).
fonte
Talvez
atop
possa lançar alguma luz sobre o seu problema.Ele pode mostrar os processos que já foram encerrados e a CPU , memória , disco e utilização da rede .
Você pode executá-lo de maneira interativa, deixá-lo gravar em um arquivo de texto ou executá-lo como
sar
em um intervalo predefinido, criando um arquivo de histórico binário pelo qual você poderá avançar posteriormente.Eu o uso para encontrar porcos de todos os tipos que são difíceis de encontrar :-)
fonte