[FUG-BR] HZ no Kernel
Luiz Otavio O Souza
lists.br em gmail.com
Quinta Janeiro 27 23:06:39 BRST 2011
On Jan 27, 2011, at 3:48 PM, Eduardo Schoedler wrote:
> Pessoal,
>
> Como não vou usar polling nesses servers, estou diminuindo o HZ=2000 para
> HZ=1000.
> Apesar de eu ter recompilado e reiniciado, aparentemente ele continua
> rodando com o valor antigo:
>
> # vmstat -i | egrep '^cpu.:'
> cpu0: timer 19533478 1990
> cpu1: timer 19533398 1990
> cpu2: timer 19577677 1995
> cpu5: timer 19498908 1987
> cpu3: timer 19577677 1995
> cpu6: timer 19565494 1994
> cpu4: timer 19498908 1987
> cpu7: timer 19565495 1994
>
> # cat /usr/src/sys/amd64/conf/BORDER-RTR | grep HZ
> options HZ=1000
>
> Já tentei até colocar no /boot/loader.conf:
> kern.hz=1000
>
> E mesmo assim continua rodando com valores antigos...
>
> # uname -a
> FreeBSD servidor 8.2-PRERELEASE FreeBSD 8.2-PRERELEASE #1: Thu Jan 27
> 12:09:04 BRST 2011
> root em servidor:/usr/obj/usr/src/sys/BORDER-RTR amd64
>
> Alguma sugestão ?
>
>
> Obrigado,
>
> --
> Eduardo Schoedler
Eduardo,
Esse é o normal... 2 vezes mais interrupções que o HZ, veja um exemplo de um servidor aqui:
mail# sysctl kern.hz
kern.hz: 1000
mail# vmstat -i | egrep '^cpu'
cpu0: timer 211101849 1998
cpu1: timer 211101513 1998
cpu7: timer 211101512 1998
cpu2: timer 211101513 1998
cpu5: timer 211101513 1998
cpu3: timer 211101514 1998
cpu6: timer 211101512 1998
cpu4: timer 211101513 1998
Existe essa outra sysctl que apresenta uma descrição mais completa dos vários timers do sistema:
mail# sysctl kern.clockrate
kern.clockrate: { hz = 1000, tick = 1000, profhz = 2000, stathz = 133 }
Pelo pouco que pude levantar aqui (use the source luke...) o profhz é o clock para profiling de utilitários (parece que o kernel executado com maiores valores de HZ contribui para a precisão do profiling - sem garantias aqui, meu entendimento aqui pode estar _muito_ errado - sou só um curioso aqui...).
Bem, no arquivo sys/kern/kern_clocksource.c (http://svn.freebsd.org/viewvc/base/head/sys/kern/kern_clocksource.c?revision=217326&view=markup) há mais algumas dicas de como isso funciona:
/*
* We honor the requested 'hz' value.
* We want to run stathz in the neighborhood of 128hz.
* We would like profhz to run as often as possible.
*/
if (singlemul <= 0 || singlemul > 20) {
if (hz >= 1500 || (hz % 128) == 0)
singlemul = 1;
else if (hz >= 750)
singlemul = 2;
else
singlemul = 4;
}
Nesse trecho é calculado o 'singlemul' (documentado como 'Multiplier for periodic mode') a partir do valor de hz utilizado (quanto menor o valor de hz, maior será o multiplicador). Depois esse multiplicador é utilizado na função setuptimer() (no mesmo arquivo):
singlemul = MIN(MAX(singlemul, 1), 20);
freq = hz * singlemul;
while (freq < (profiling ? profhz : stathz))
freq += hz;
freq = round_freq(timer, freq);
FREQ2BT(freq, &timerperiod);
E isso acaba resultando (no caso de HZ=1000) que a frequencia do timer seja (basicamente) = HZ * 2.
E indo um pouco além, da para prever que com HZ=2000 o multiplicador será '1' e a frequencia do timer também será de 2000 (divertido, não ? :))
Espero que isso ajude a clarear de onde vem e como são calculados esses valores (espero que tenha sido útil para você como foi útil para mim).
Se você (ou alguem) quiser mais detalhes, recomendo começar pelo arquivos kern/subr_param.c, kern/kern_clock.c além do arquivo que já citei.
[]'s
Luiz
Mais detalhes sobre a lista de discussão freebsd