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