<figyelem, régi topic!>
Eljutottam arra pontra, hogy már muszáj kérdeznem...
Adott egy alaplap (MSI MS-7519 Intel P43+ICH10 chipset), valamint egy (igazából több) Samsung 830 SSD.
A következő módon próbáltam az SSD-t tesztelni:
Teleírás "random" (de mindig reprodukálhatóan azonos) adattal:
dd if=/dev/zero bs=8192 count=31257387 | openssl enc -rc4 -nosalt -pass pass:sample | sudo dd of=/dev/sdb bs=8192
Visszaellenőrzés:
dd if=/dev/zero bs=8192 count=31257387 | openssl enc -rc4 -nosalt -pass pass:sample | sudo cmp -l - /dev/sdb
Normális körülmények között (pl a fenti SSD egy másik gépben) a cmp nem talál különbséget. Tehát az SSD és a tesztelési módszer alapvetően jó.
Viszont ebben a gépben talál különbségeket. Ez egy futásnál kapott példa. Az olvasást megismételve pontosan ugyanezt kapom vissza, viszont az írást megismételve más helyekre kerülnek a hibák, a számuk is kicsit változik +/- 1-2, de nagyságrendileg ugyanennyi marad.
692658557 20 220
29539541373 114 314
60075553149 162 362
75365245309 173 373
82996355453 131 331
90628153725 150 350
98256822653 33 233
105894486397 172 372
113515381117 173 373
143955181949 124 324
159206035837 23 223
182105842045 111 311
197371572605 73 273
205012619645 164 364
220288868733 52 252
235546464637 37 237
Annyi látszik, hogy a hiba nem az olvasás során kerül oda, hanem az írásnál - szar ügy. Továbbá a hibákban van rendszer, egyrészt az oktális számokból látszik, hogy mindig a byte lefelső bitje billen 0-ról 1-re, másrészt (ez ránézésre nem ennyire nyilvánaló, de binárisra átszámolva már igen), a cím alsó 12 bitje mindig azonos, 0x17d. Más rendszert nem találtam benne, és sajnos ez nem mond sokat a hiba okáról. Annyit talán igen, hogy mivel pontosan 1 bit tér el, ezért nem történhet paritással védett csatornán, mert annak meg kéne fognia.
A smart nem jelez UDMA CRC errort, vagyis az SSD nem érzi úgy, hogy a SATA fizikai rétegben gond lenne. Mivel ugyanez az SSD másik gépben hibátlanul veszi a tesztet, valamint a media read/write failure attribútumok is fixen 0-n állnak, ezért arra következtetek, hogy valahol feljebb lesz a hiba.
Hibát nem jelez:
- dmesg (3.6.10-1, x86_64 Arch linux)
- memtest86+ 4.2. Az 5-ös teszt akár órákon át futva is hibátlan (random memóriahibát ennek kéne megfognia).
- dd if=/dev/zero bs=8192 count=31257387 | openssl enc -rc4 -nosalt -pass pass:sample | cmp - <(dd if=/dev/zero bs=8192 count=31257387 | openssl enc -rc4 -nosalt -pass pass:sample) - hibátlan tehát nem a CPU hibázik a random stream előállítása közben
Nincs hatása:
- SATA port cserelgetés nem változtat
- SATA kábel cserélgetés nem vátloztat
- SSD cserélgetés nem vátloztat (olyan HDD most nincs kéznél, amiről törölhető minden)
- nincs tuning
- egyéb kártyák (tv tuner) jelenléte nem számít
Valamilyen szinten hatással van:
- Az déli híd hőmérséklete. Ha ventilátorral hűtöm az ICH10-et, akkor a ~16 hiba lemegy 4-7db-ra.
- Az ICH tápfeszültsége. A default 1.5V-tal a legjobb, magasabbra állítva valamelyest romlik. Lejjebb állítani viszont nem lehet.
- AHCI módból legacy IDE módba kapcsolni. Sajnos ez is csak ront a helyzeten. Amellett, hogy kb 20%-al lassabb, kb 2-3x annyit hibázik is.
Az ICH sajnos nem PCIe-n hanem valami Intel-proprietary DMI interfészen keresztül kapcsolódik az északi hídhoz. Nem találtam nyomát, hogy be lehetne-e kapcsolni a DMI linken olyan paritáshiba-jelzést, mint pl a PCI SERR#.
NMI viszont van, most éppen 2800 körül jár a számláló, és fogalmam sincs, hogy hogyan tudnám kideríteni, hogy mitől jönnek. Olyankor is jön, amikor a SATA porthoz hozzá sem nyúlok (az OS egy PATA diszkről megy).
Nem találtam módot arra sem, hogy a SATA2-es (3Gbit/s) jelzési sebességet visszavegyem 1.5Gbit/s-re. Mondjuk önmagában röhej, hogy mindenhol erre a módszerre hivatkoznak: http://www.ehow.com/how_7331892_set-sata-speed-adapter-linux.html ami akkora hülyeség, hogy párját ritkítja. man hdparm és rögtön látszik, hogy mekkora ökörség. Sajnos Alan Cox szerint korábban nem volt kivezetett interfész rá, a kernel magától visszaveszi a segességet, ha sokat hibázik port - feltéve ha észreveszi. BIOS-ban természetesen nincs állítási lehetőség.
Szóval most kicsit tanácstalan vagyok. A "dobd ki az alaplapot" jellegű megoldást magamtól is ki tudom találni. "Vegyél másik SATA vezérlőkártyát" - szintén. Rááadásul a PCIe x1 foglalatok is az ICH10-ből jönnek, tehát ha a hiba a DMI link környékén vagy az ICH10 belső PCIe bridge-ben van, akkor a kártyás SATA vezérlővel is hibázni fog. Parallel PCI szintén ICH10-ről jön, ráadásul SSD-hez az igencsak lassú is. Ezen kívül csak a PCIe x16-os van közvetlenül az északi hídról amiben a grafkártya ül - nehéz lenne ide rakni SATA vezérlőt.
Tehát valami szoftveres megoldás kéne, hogy üzemszerű működés során legalább jelezze, ha hiba van. Még jobb, ha esetleg javítani is tudja. El tudom képzelni, hogy ilyen hiba nem csak engem érint, csak éppen sokan nem is tudnak róla. Illetve ha kicserélem az alaplapot ki tudja, hogy nem ugyanilyen hibásat kapok-e. Tapasztalatból tudom, hogy egy OS simán el tud működni a hibás porton lógó SSD-ről futva úgy, hogy a user csak hébe-hóba egy-két érthetetlen furcsaságot tapasztal, de nem jön rá, hogy mitől. Lényegében már az segítene, ha írás után a kernel visszolvasná a kiírt adatot és 1) dobna errort, ha nem egyezik 2) esetleg megismételné az írást.
UPDATE: a megoldás végül elod kollégától jött. A sima memtest86+ helyett memtest86 4.0a multithreaded változat kellett, hogy kifogjon egy memóriahibát. A hiba címének utolsó 12 bitje egyezett a diszken talált hibák utolsó 12 bitjével (ami jogos, ha az adat többnyire egész page-enként másolodik a memóriábol). Erre lényegében csak ECC-s memória jelent korrekt megoldást, más integritás-ellenörző módszer legfeljebb véltelen foghatta volna meg.
Az ötleteket mindenesetre köszönöm mindenkinek!
UPDATE2: most volt időm kicsit kisérletezni. Nyilván az érintett memóriamodul előbb-utóbb útnak indul a szemetes felé, de előbb megpróbáltam szoftveresen kizárni a hibás memóriaterületet. Erre régen volt a badram/badmem patch, akkoriban egy P1-es gépben még használtam is. Most utánanéztem, mi a korszerű megoldás erre, szerencsére már nem kell kernel patch hozzá. A grub2 ki tudja zárni az érintett területet a BIOS e820 memory range-ek módosításával (egészen pontosan nem egy reserved range-et vesz fel - ahogy elsőre gondolnám - hanem a usable range-et bontja két részre és kihagyja a lyukat). Így elvileg bármilyen e820-at tiszteletben tartó oprendszer számára hatásos lesz a kizárás. Megjegyzem emiatt a memtest86-ra is hatni fog, de legalább könnyu kipróbálni, hogy jó lett-e.
/etc/default/grub
-ba
GRUB_BADRAM="0x001bbca317c,0xffffffffff0"
Figyelem, ne higgyünk a memtest86 Badram Addresses kijelzési módnak, az levágja a címet 32 bitre. Ettől még könnyen lehet hogy jó lesz, mert a maszkot is levágja, csak szűkségtelenül zárunk ki több területet.
sudo grub-mkconfig -o /boot/grub/grub.cfg
Annyi történt, hogy a /boot/grub/grub.cfg
header részbe (tehát nem a konkrét boot entry-khez) bekerült ez
badram 0x001bbca317c,0xffffffffff0
Reboot.
Először is memtest86, ezuttal szigorúan 4.0a.
Ja igen, ha nem lenne meg, mert a grub-mkconfig alapból nem generálja, akkor
sudo cp /etc/grub.d/20_memtest86+ /etc/grub.d/42_memtest86_custom
majd a 42_memtest86_custom
scriptben a MEMTEST86_IMAGE=
változót átírni ahová a memtest86-4.0a.bin került.
A memtest86 ezúttal hibátlanul viszi az összes tesztet. Ez egyrészt jó, mert jól kihagytuk a hibás részt, de rossz is, mert a memtest-et nem azért tartja az ember, hogy ne találja meg a hibákat. Elvileg erre is van megoldás (még nem próbáltam), a badram 0x001bbca317c,0xffffffffff0
sort a headerből a menuentry alá kéne tenni, és akkor csak az adott entry-re érvényes. Ehhez viszont a grub-mkconfig-ot némileg át kéne szabni, ezt egyelőre nem csináltam meg.
Jöhet a rendes boot. dmesg-ben a következő memory map figyel:
[ 0.000000] e820: BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009e7ff] usable
[ 0.000000] BIOS-e820: [mem 0x000000000009e800-0x000000000009ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000000e0000-0x00000000000fffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000bff8ffff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000bff90000-0x00000000bff9dfff] ACPI data
[ 0.000000] BIOS-e820: [mem 0x00000000bff9e000-0x00000000bffdffff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x00000000bffe0000-0x00000000bfffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fee00000-0x00000000fee00fff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000ffb00000-0x00000000ffffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x00000001bbca2fff] usable
[ 0.000000] BIOS-e820: [mem 0x00000001bbca3400-0x000000023fffffff] usable
Látható, hogy a 0x1bbca3000-0x1bbca33ff tartomány ki van hagyva. Furcsa, hogy miért pont 1024 byte, én egy egész 4k-s page-re számítottam volna.
Végül a teljesség kedvéért a diszk írási teszt is megismétlésre került, és ezúttal teljesen hibátlan!
A memóriamodulban ettől azért még nem bízom, előbb-utóbb repülni fog a gépből. Egy reinstall vagy bármi más kisérletezés után igen könnyen elfelejtődhet, hogy a hibás tartományt ki kell hagyni.
UPDATE 3:
sok évvel az eredeti után :)
A módszer kicsit elavult az NVMe-s SSD-k korában, Core i7-4790-en rc4-el kb 590MB/s jön ki. Viszont ha van AES-NI a processzorban, akkor -aes-128-ctr lényegesen gyorsabb lehet, kb 1.5-1.9GB/s (pontosan most nem tudom kimérni, mert az alaplapomon nerf-ölt m.2 slot van, ami PCIe 2.0 x2, kb 850MB/s-et ereszt át).