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

--
FreeBSD mailing list (users-l@freebsd.cz)
http://www.freebsd.cz/listserv/listinfo/users-l

Odpovedet emailem