HP server a problémy s real-time
Pavel Troller
patrol na sinus.cz
Čtvrtek Duben 14 05:15:16 CEST 2011
Zdravím,
mám tu zase jeden opravdu zapeklitý případ pro počítačové experty :-).
Zakoupili jsme na firmě tento server:
Manufacturer: HP
Product Name: ProLiant DL120 G6
Jde o 1U pizzabox, čtyřjádrový xeon @ 2.66 GHz, k tomu hyperthreading,
paměti pro danou aplikaci dostatek (4G).
Server má sloužit jako telefonní ústředna Asterisk, pro účel čehož je
v něm vložena karta 8xE1 Sangoma.
Problém je, že server trpí pravidelnými krátkodobými výpadky chodu, kdy
v určitých relativně přesných časových intervalech "mrzne" na dobu až
desítek milisekund a pak se zase rozbíhá. Lépe než slovní popis to vysvětlí
ukázka výpisu maličkého diagnostického prográmku:
Extensive sleep: 2441 usecs.
Freeze interval: 2343820 usecs.
Extensive sleep: 1934 usecs.
Freeze interval: 2343454 usecs.
Extensive sleep: 2145 usecs.
Freeze interval: 2343205 usecs.
Extensive sleep: 1678 usecs.
Freeze interval: 2343493 usecs.
Extensive sleep: 777 usecs.
Freeze interval: 2342056 usecs.
Extensive sleep: 2370 usecs.
Freeze interval: 2345172 usecs.
Extensive sleep: 707 usecs.
Freeze interval: 2341719 usecs.
Extensive sleep: 2077 usecs.
Freeze interval: 2344949 usecs.
Extensive sleep: 1325 usecs.
Freeze interval: 2343499 usecs.
Extensive sleep: 2121 usecs.
Freeze interval: 2343508 usecs.
Extensive sleep: 1311 usecs.
Freeze interval: 2343476 usecs.
Extensive sleep: 2020 usecs.
Freeze interval: 2343395 usecs.
Extensive sleep: 1716 usecs.
Freeze interval: 2343839 usecs.
Extensive sleep: 2101 usecs.
Freeze interval: 2343219 usecs.
Extensive sleep: 1310 usecs.
Freeze interval: 2343460 usecs.
Extensive sleep: 2139 usecs.
Freeze interval: 2343560 usecs.
Extensive sleep: 1815 usecs.
Freeze interval: 2343826 usecs.
Extensive sleep: 2360 usecs.
Freeze interval: 2343387 usecs.
Zdrojový text jest zde:
# cat timetest.c
#include <sys/time.h>
#include <sys/types.h>
#include <sched.h>
#include <stdio.h>
void main () {
struct timeval tv1,tv2,tv3,tv4;
int diff, diff2, diff3;
struct sched_param sp;
sp.__sched_priority=99;
if (sched_setscheduler(0, SCHED_FIFO, &sp)) {
perror("sched_setscheduler failed:");
}
gettimeofday(&tv1,0);
gettimeofday(&tv2,0);
gettimeofday(&tv3,0);
gettimeofday(&tv4,0);
for (;;) {
gettimeofday(&tv1,0);
usleep(50);
gettimeofday(&tv2,0);
diff=(1000000*tv2.tv_sec+tv2.tv_usec)-(1000000*tv1.tv_sec+tv1.tv_usec);
if (diff > 500) {
printf("Extensive sleep: %d usecs.\n",diff);
diff3=(1000000*tv2.tv_sec+tv2.tv_usec)-(1000000*tv4.tv_sec+tv4.tv_usec);
if (diff3 > 1000000) {
tv4=tv2;
printf("Freeze interval: %d usecs.\n", diff3);
}
}
}
}
Logika je myslím jasná - program se nechá na 50 us uspat a pak si změří, kolik
spal ve skutečnosti. Pokud je to více než 500 us (tj. desetkrát tolik), vypíše
tuto hodnotu a navíc čas, který uplynul od minulého "zaspání". Nu a je vidět,
že k "zaspání" dochází pravidelně po nějakých 2.34 sekundách. Pár dalších
poznámek:
- Prográmek si nastavuje nejvyšší možnou real-time prioritu, nemělo by tedy
existovat nic, co by jej dokázalo dostat od procesoru - vždyť tam jsou 4
plnohodnotná jádra, jedno by mělo být pro něj vždy k dispozici.
- Interval mezi "zaspáními" se v čase nemění, co se ale mění, je délka
"zaspání", ta v čase vzrůstá. Tato ukázka s průměrnou délkou zaspání 1 - 2 ms
vznikla po cca dvou dnech běhu. Rekord jsem naměřil po 45 dnech, kdy už bylo
jedno každé zaspání od 10 do 30 ms a někdy se stávalo, že v tomto intervalu
se úloha na chvilku "probrala", takže se to vypsalo jako 2 - 3 menší "zaspání"
těsně za sebou.
- Na zaspání se nepodílí chod čehokoliv v systému - test byl měřen, aniž by
běžel jakýkoliv server (včetně toho asterisku), s odpojenými
a odkonfigurovanými ethernet porty, dokonce se shutdownovanými disky.
- Závada byla již reklamována u výrobce, který vyměnil základní desku. Nová
dělá totéž.
- Bylo testováno několik jader (2.6.34, 36, nyní 38.2) a závada se projevuje
zcela identicky.
- Na solidnějším bratříčkovi tohoto serveru (Proliant DL360 G6) běží zcela
identický software (instalovaný z téhož image) již nějakých 400 dní, aniž by
se uvedená závada jakkoliv projevila. Pokud tam spustím výše uvedený program,
také něco vypisuje, ale jedno zaspání kolem milisekundy se objeví v řádu
desítek hodin, nadto zcela stochasticky. To jsem ochoten tolerovat.
- I můj domácí server, řadové PC od Asusu, s výrazně slabším CPU (běžící
rovněž tentýž image) se chová výrazně lépe, sice "zakopne" častěji než ten
DL360, tak jednou za 4 - 6 hodin, ale opět zcela stochasticky a jen na
krátkou dobu.
Napadá někoho, co tomu krámu je a jak tomu odpomoci ? Velmi hrubý workaround
je stroj každou noc rebootovat, neboť během jednoho dne nenaroste zpoždění
do takových hodnot, že by to vadilo (Asterisk tu milisekundu nedostupnosti
prostě "překlene", i data z těch E1 karet se stačí vyčíst). Je to ale jen
nejvyšší nouze a rozhodně to nehodlám dlouhodobě takto provozovat.
Taky by mi pomohlo, kdyby by tu byl někdo, kdo provozuje tutéž platformu
a byl by ochoten si tam ten prográmek zkompilovat a na chvilku pustit, abychom
viděli, zda to dělají prostě všechny servery, nebo jen ten náš (přeci jen
nebylo vyměněno vše, např. RAID karta zůstala původní a ta by teoreticky
mohla např. nějakým DMA systém blokovat.
S pozdravem Pavel
Další informace o konferenci Hw-list