Instabilidade do relógio no Debian 9 (trecho)

3

Eu tenho uma máquina rodando Debian 8 (jessie) rebaixada para o kernel 3.2-rt. Isso está executando um aplicativo que é definido para a prioridade em tempo real (SCHED_RR), acorda a cada 1ms para fazer algum processamento, e a cada 100ms envia uma mensagem serial para outro PC. Isso funciona perfeitamente. (A máquina realmente não executa nada além dos serviços padrão; em particular, não é uma máquina desktop.)

Ao tentar atualizar isto para o Debian 9 (stretch) com o kernel 4.9-rt eu encontrei problemas consideráveis; Um dos maiores problemas é a estabilidade do relógio. Embora inicialmente pareça rodar ok, pouco tempo depois da inicialização eu recebo isso:

clocksource: timekeeping watchdog on CPU0: Marking clocksource 'tsc' as unstable because the skew is too large:
clocksource:                       'acpi_pm' wd_now: 74c6dd wd_last: 8dd916 mask: ffffff
clocksource:                       'tsc' cs_now: 119ac91c7b1 cs_last: 1158a25441d mask: ffffffffffffffff
clocksource: Switched to clocksource acpi_pm

Na primeira vez que isso ocorreu, a mensagem acima relatou a mudança para "hpet"; depois que essa opção ocorreu, todo o tempo na máquina parecia estar instável - o código usa clock_gettime(CLOCK_MONOTONIC, ...) para sincronismo e isso estava reportando que agora ele estava acordando a cada 4ms em vez de 1ms, a mensagem serial estava sendo transmitida a cada 200ms em vez de cada 100ms, mas os timestamps dentro da mensagem serial indicavam que estava enviando a cada 66ms. (É possível que alguns deles estivessem contando ticks de ativação em vez de ms reais.)

Eu tentei desativar o HPET no BIOS, o que levou ao erro mostrado acima, e novamente ele roda ok até inicializar o ponto acima, enquanto parece funcionar, algumas vezes alguns temporizadores relatam durações negativas.

A outra coisa principal errada é que o código de processamento que roda a cada 1ms leva cerca de 200us para ser executado em Jessie, mas 900us para ser executado no Stretch, sem nenhuma razão aparente. Eu tentei executar perf record sobre ele e ele relata que a maior parte do tempo (40% das amostras) está sendo gasto em sys_clock_gettime .

Este é o mesmo hardware em ambos os casos: uma placa-mãe Supermicro X11SSQ com um CPU i7-7700K na arquitetura AMD64. A aceleração da CPU está desativada no BIOS e reporta constant_tsc e nonstop_tsc .

Possivelmente de interesse é que o aplicativo estava fazendo um loop de espera ocupada ( if clock_gettime() < wakeup then sched_yield() , no pseudocódigo simplificado) para agendar o código de processamento.

Como experiência, eu mudei para dormir ( clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wakeup) ) e pelo menos até agora o erro da fonte clocks não voltou a ocorrer e ele permaneceu usando o clock tsc, que parece funcionar corretamente (diferente dos outros relógios ).

No entanto, o jitter de despertar é agora 10x pior: 700-1200us (SD 36us) para o sono vs. 890-1120us (SD 2us) para espera ocupada.

Como experimento adicional, tentei alterá-lo para SCHED_DEADLINE (com um único sched_yield() ), mas isso tem o mesmo comportamento de clock_nanosleep.

Alguma idéia de por que esse comportamento mudou entre Jessie e Stretch (ou entre 3.2 e 4.9, mais provavelmente)? Existe uma maneira melhor de realizar uma espera de pouca instabilidade sem aparentemente quebrar o relógio do sistema?

    
por Miral 11.07.2017 / 06:30

1 resposta

0

em /etc/default/grub adicione "notsc clocksource = acpi_pm" na linha GRUB_CMDLINE_LINUX_DEFAULT

Meu agora é:

GRUB_CMDLINE_LINUX_DEFAULT="quiet notsc clocksource=acpi_pm"

Em seguida, faça: sudo update-grub

Você pode definir outros clocksources disponíveis:

cat /sys/devices/system/clocksource/clocksource0/available_clocksource
    
por 18.02.2018 / 12:59