System mi nenachazi zarizeni 2 (tezsi uvod do troubleshootingu detekce zarizeni).
Dan Lukes
dan at obluda.cz
Mon May 11 18:23:50 CEST 2020
Pred chvili jsem v jinem emailu lehce nactrtnul jak vypada PCI sbernice
v pocitaci a jak na ni FreeBSD nachazi zarizeni a hleda pro ne ovladace
a o chvili pozdeji v dalsim mailu popisoval reseni chybejicich ovladacu.
V tomhle poslednim bych se zkusil povenovat situaci, kdy system vubec
nevidi zarizeni pripadne celou sbernici.
K analyze tohohle problemu je potreba system startovat ve verbose rezimu
a vystup bootu si chytit do souboru.
V nem je pak potreba sledovat proces detekce zarizeni a hledat "cokoliv
divneho". Coz je, uznavam, dost vagni popis, takze se pokusim nactrtnout
co divny neni.
Detekce PCI zarizeni zacina od bridge, ktery je mezi procesorem a prvni
smernici. Ten se vzdycky (alespon doufam) jmenuje pcib0. Ve verbose LOGu
tedy hledame neco jako:
> pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
Za nim muze byt jeden nebo vice zaznamu o adresnich rozsazich, ktere
tento bridge prenasi, coz jsou radky zacinajici
pcib0: decoding ...
Pote, co je nadetekovan bridge, je za nim ovladacem toho bridge nalezena
nejmene jedna PCI sbernice. Pocita se od nuly, takze ta prvni bude pci0
> pci0: <ACPI PCI bus> on pcib0
> pci0: domain=0, physical bus=0
Druhy z tech dvou radku rika, ze pci0 je prvni smernice prvniho PCI stromu.
Po nalezeni PCI sbernice zacina faze evaluace jednotlivych zarizeni,
ktera jsou na ni pripojena. Zaznam o kazdem zacina "found ->" a
nasleduji zakladni udaje o nalezenem zarizeni. Muze vypadat napriklad
takhle:
> found-> vendor=0x1022, dev=0x1481, revid=0x00
> domain=0, bus=0, slot=0, func=2
> class=08-06-00, hdrtype=0x00, mfdev=1
> cmdreg=0x0044, statreg=0x0010, cachelnsz=0 (dwords)
> lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
> MSI supports 4 messages, 64 bit
Vendor a dev jsou cisla identifikujici vyrobce a konkretni zarizeni, rev
je "verze" zarizeni.
Domain a bus je cislo PCI stromu a sbernice a melo by vzdy souhlasit s
udajem "domain=0, physical bus=0" sbernice, kterou prave prochazime.
"Slot" je poradi zarizeni na sbernici (cisla by mela byt rostouci,
nemusi ale tvorit neprerusenou radu).
V prvnim emailu jsem mluvil o tom, ze jedno fyzicke zarizeni v sobe muze
skryvat vic zarizeni virtualnich - tak "func=" je poradove cislo
virtualniho zarizeni v zarizeni fyzickem.
"Class" je trida zarizeni, tedy vlastne neco jako obecny typ. Na vyznam
cisel se muzete podivat sem: http://pci-ids.ucw.cz/read/PD/
Posledni udaj, ktery chci popsat je "hdrtype". Jednicku ma PCI-PCI
bridge, nulu naprosta vetsina ostatnich zarizeni. Dvojka u PCI->Cardbus
bridge. Nic jineho by tam byt nemelo.
Zaznam obsahuje i dalsi informace, a muze jich tam byt jeste vic nez
kolik je videt v prikladu shora. Byvaji tam informace o podporovanych
powermanagementovych rezimech, o zdrojich (adresnich blocich) a
prerusenich, ktere zarizeni pozaduje, informace o podpore HotPlug a
mozne informace o dalsich podporovanych funkcich a moznostech. Temi s
enebudeme zsabyvat detailneji, ale na druhou stranu, pokud zjistite, ze
problematicka zarizeni maji neco spolecneho, napriklad kazde ma nejakou
konkretni vlastnost, zatimco ta co ji nemaji problem nemaji, muzete mit
dulezitou stopu.
Jen pro jistotu upozornuju, ze kdyz jsme v tomhle nebo predchozich
mailech pouzil slovo "bridge" bez privlastku, myslel jsem tim PCI-PCI
bridge (tedy bridge mezi dvem PCI smernicemi) a nikoliv jine typy.
Jeste uvedu priklad nalezeneho PCI-PCI bridge:
> found-> vendor=0x1022, dev=0x1483, revid=0x00
> domain=0, bus=0, slot=3, func=1
> class=06-04-00, hdrtype=0x01, mfdev=1
> cmdreg=0x0147, statreg=0x0010, cachelnsz=0 (dwords)
> lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
> powerspec 3 supports D0 D3 current D0
> MSI supports 1 message, 64 bit
> secbus=1, subbus=1
Vidite class 06-04-* a hdrtype=0x01, nas ale nejvic zajima informace
"secbus=1, subbus=1" coz je oznaceni PCI sbernice, ktera je "za bridgem".
Pote co system radky "found ->" probehne vsechna zarizeni na konkretni
sbernici, zacne pro ne hledat ovladace.
Smula je, ze zde uz nektere informace vypisuji samotne ovladace a ruzn
eovladace nedodrzuji uplne jednotnou kulturu, takze se format i mnozstvi
vypisovanych informaci muze trochu lisit, ale rozdily nebyvaji
neprekonatelne velke.
Vratim se na chvili k "found ->" prikladu. Nem bylo "domain=0, bus=0,
slot=3, func=1". Vime, ze "domain=0, bus=0" je pci0 a je to prvni
virtualni zarizeni v ramci tretiho fyzickeho zarizeni te sbernice.
Odpovidajici zaznam o nalezeni ovladace vypada takhle:
> pcib1: <ACPI PCI-PCI bridge> at device 3.1 on pci0
takovy radek byste melo najit pro jazde "found ->" zarizeni a mely by
byt ve stejnem poradi v jakem byly found radky, s prihlednutim k
"odskokum" do podrizenych sbernic za bridgi. To znamena, ze byste meli
poznat, kdyz nejake "found->" zarizeni bylo preskoceno a neexistuje k
nemu zaznam o detekci ovladace.
Vyjimkou jsou prvni virtualni zarizeni u multifunkcnich
(virtualizovanych) fyzickych karet (tedy ta, ktera maji func=0) - to je
PCI-Host bridge, ten odpovidajici radek s detekci ovladace nema.
Po pruchodu celym logem byste melo byt schopni nakreslit strom sbernic,
pripojena zarizeni na jednotlivych sbernicich a ke kazdemu mit
identifikovany ovladac, vyslovnou informaci, ze system ovladac nenasel.
Primarne ale hledate jakakoliv chybova hlaseni - napriklad, ze se
nekteremu zarizeni nepodarilo pridelit pozadovane adresni bloky nebo
neco podobneho. Na reseni tohoto problemu neexistuje univerzalni navod,
ale vedet kde je problem je pro reseni vhodna startovaci pozice.
Nejhur se hleda chyba spocivajici v tom, ze se nenajde nektera z
podrizenych sbernic (at uz proto, ze se nenajde nebo nespravne
identifikuje bridge, ktery ji pripojuje nebo proto, ze se nezdari jeho
incializace) a take chyba, kdy se podrizena sbernice sice najde, ale
nenacte se seznam zarizeni, ktere jsou an ni pripojene (a nasledne se
tedy neenumeruji). Problem je v tom, ze pokdu nevite (a to vetsinou
nevite) jaka topologie PCI sbernice ma vyjit, pak nepoznate, ze na tom
stromu, ktery jste si namalovali, neco chybi.
V takovem pripade muze "zazracne" pomoct, pokud zjistite, ze nejaky jiny
operacni system problem s detekci problematickeho zarizeni (nebo skupiny
zarizeni) problem nema, dokazete ziskat informace o topologii sbernice z
nej a porovnat tenhle strom s tim, ktery si namalujete na FreeBSD.
Ani v tomto pripade nemuzu slouzit universzalnim navodem jak reagovat na
zjistene rozdily, i tentokrat je ale identifikace rozdilu zasadnim
krokem k reseni.
Na zacatku jsme rikal, ze tenhle "serial" vzniknul proto, ze jsem s
Mirou Lachmanem resil nedetekovana NVMe zarizeni. Kdyz nemuzu dat
univerzalni navod, pouziju to alespon jako "modelovku" a velmi strucne
proces analyzy a nalezene reseni.
K dispozici byl zaznam verbose bootu a pciconf z FreeBSD, a lspci -tvv z
Linuxu, ktery zarizeni videl, u ktereho ale byl problem, ze ho neznam
natolik detailne, abych si byl uplne jisty interpretaci vsech detailu,
ktere lspci poskytnul.
Problem nejprve probehl anglickou konferenci, kde Scott vyslovil
hypotezu, ze se neenumeruji podrizene sbernice s cisly >=128. Podle
dopstupnych informaci to totiz vypadalo, ze MVMe zariznei jsou pripojena
prave na sbernici 128. Ja ale po kompletni analyze verbose bootu nasel
zarizeni v proadku pripoejna na sbernici 131, takze se mi to moc
nepozdavalo.
Vyslovil jsem jinou teorii, ze to co povazujeme za bridge ke sbernici
128 je chyba v identifikaci zarizeni, nejde o bridge, ale je to primo
radic NVMe. Takze jsme donutil Mirka aby prelozil upraveny kernel, kde
modifikoval ovladace tak, aby se k dotcenym zarizenim priupojil ovladac
pro NVMe. Slo o relativne jednoduchy pokus, ktery ale nevysel. Pri
druhem cteni verbose logu jsme si vsimnul, ze nektere bridge vcetne
toho, za kterym je sbernice 128 maji funkci "HotPlug" a za zadnym z nich
neni nadetekovane jedine zarizeni. Nova teorie tedy znela, ze chyba je v
obsluze HotPlug sbernic, ktere funguji tak, ze pri pripojeni zarizeni
vyslou systemu zpravu ten nasledne sbernici enumeruje znovu pricemz
pripoji nova zarizeni. Nemam nastudovanou "spravnou funkci" Hot Plug,
takze nevim, jestli by pri prvni incializaci mel bridge systemu zpravu
"zmena v zarizenich" poslat a nas bridge to neudela (tedy jde o chybu HW
chipu) nebo by system mel pri prvnim pripojeni HotPlug sbernici tuto
enumerovat i bez specialniho signalu (a tedy jde o chybu implementace ve
FreeBSD). To ale pro reseni nebylo podstatne, protoze podporu pro
HotPlug jde pomoci sysctl vypnout (a ke vsem brodge se pak pristupuje
jako by HotPlug nemely).
Po vypnuti HotPlug system NVMe zarizeni na sbernici 128 normalne nasel a
cele to zacalo fungovat.
Toz tak. Pokud se k tomu nekdo chce na neco optat, co budu vedet tak
zodpovim. Pripominam, ze jsem celou problematiku znacne zjednodusil, ale
i tyhle zaklady muzou pomoct resit jednodussi problemy.
Jestli neco z toho co jsem napsal nekdy nekomu pomuze tak dobry, jestli
ne, tak to se neda nic delat. Neni to prvni cas, kterej bych propalil
zbytecne ;-)
Dan
More information about the Users-l
mailing list