Implementácia a náročnosť SW bridge

Implementácia a náročnosť SW bridge
« kdy: 16. 09. 2018, 19:53:00 »
Ahoj, vedel by mi niekto osvetliť, akým spôsobom je implementované softvérové premostenie dvoch sieťových rozhraní v linuxe? Ak správne rozumiem, bežný sieťový adaptér používa DMA a prenášané dáta zapisuje/číta priamo z RAM a tým je menej zaťažený samotný procesor. Ako to ale funguje pri premostení dvoch rozhraní? Musí procesor skopírovať všetky dáta z jedného miesta v pamäti na iné, alebo tieto dve rozhrania môžu pamäť zdielať a úlohou CPU je akurát celý tento proces riadiť? Vďaka.


Re:Implementácia a náročnosť SW bridge
« Odpověď #1 kdy: 16. 09. 2018, 20:46:41 »
Na 99% se vsadím, že sw bridge funguje přes RAM a je řízena CPU. Už proto, že je tam nějaká logika, například, že některé pakety mohou být určeny tomu SW bridge a není možné je jen hloupě přeposlat

Honza

Re:Implementácia a náročnosť SW bridge
« Odpověď #2 kdy: 16. 09. 2018, 23:23:28 »
Zajimave tema, myslim ze hodne zalezi na hw, protoze nektere veci muzete offloadovat viz. treba doc:

https://wiki.netfilter.org/pablo/netdev0.1/slides/Hardware-accelerating-Linux-network-functions.pdf

Lol Phirae

Re:Implementácia a náročnosť SW bridge
« Odpověď #3 kdy: 16. 09. 2018, 23:42:32 »
Řešení: Nepřehusťuj si myslivnu zbytečnými prkotinami a pořiď si switch...  ::)

Re:Implementácia a náročnosť SW bridge
« Odpověď #4 kdy: 17. 09. 2018, 10:51:20 »
Zkusmo jsem zagooglil ohledně Zero Copy Networking - ale tenhle termit je zjevně vyhrazen pro jednu oblast ve vyšších vrstvách, konkrétně pro kopírování mezi kernel space a user space, tzn. "baví se můj user space prográmek po síti a chtěl by rychle".

V našem případě se bavíme o soft-bridgi, což je v linuxu modul v kernelu, paket vůbec neopustí kernel. Čili dotaz zjevně zní: "kolikrát se sk_buff zkopíruje v RAMce 'zbytečně' mezi RX DMA a TX DMA?" Jasnou odpověď jsem nenašel a nemám čas ji hledat, kdyžtak se zkuste dál už potápět sám. Níže uvedu pár odkazů, odkud by snad šlo začít.

Google našel blogpost obsahující pár výživných diagramů. Obrázek je za tisíc slov. Další dva doprovodné blogposty jsou vyčerpávající, čistě textové a popisují RX a TX řetězce - ideální čtení před usnutím, pokud máte problém usnout.

Některé podrobnosti osvětlují dvě hesla na Linux Foundation Wiki, ohledně networking control flow v kernelu (hledejte nadpisy ohledně "Layer 2" nebo text "bridge") a ohledně NAPI (hledejte text "DMA"). Pokud mi paměť slouží, NAPI infrastruktura byla před lety zavedena pro snížení frekvence interruptů od síťových rozhraní.

Pokud se týče vlastního kernelového modulu, který realizuje bridge, můžete se pokochat přímo aktuálními zdrojáky. Je to hrst jednotlivých souborů. Můžete začít třeba od toho, co modul dělá při natažení do kernelu (= kam se zavěšuje), nebo se podívejte na funkce, realizující forwardování paketů... Ono k Vašemu dotazu tam na první pohled není vidět mnoho, protože skutečné "maso" je skryto za hradbou interního kernel networking API.

V textech popisujících linuxové síťoviny se často vyskytuje klíčové slovo SKB nebo struct sk_buff. Jedná se zjevně o "kus paměti obsahující jednotlivý paket". Pokud je to jen trochu možné, předávají si funkce navzájem jenom pointer (odkaz), celý buffer se pokud možno nekopíruje. Otázkou tedy je, kdy a z jaké oblasti paměti se sk_buff naalokuje a za jakých okolností se uvolní, jaká je jeho "životnost" / životní cyklus.

Zatím co jsem si tak občas přečetl v dokumentaci PCI zařízení, RX DMA funguje velmi zjednodušeně tak, že v PCI zařízení nakonfigurujete bázovou adresu + délku okna v hostitelské paměti, a v tomto okně se Vám následně vynořují data = příchozí pakety, jeden za druhým. Modernější síťovky (nejméně např. Realtek 8168, tzn. žádný výkřik raketové technologie) umí běžet podle scatter-gather seznamu, takže DMA okno nemusí být ani spojité. Tak či onak, to cílové DMA okno nebo sg-list je cyklické, používá se na způsob kruhového bufferu (ring buffer). Klíčový je fakt, že síťovka se v RX směru sama rozhoduje, kdy se do DMA pustí, a teprve až když je přenos hotový, pošle "vám" (driveru síťovky v hostitelském kernelu) interrupt, že nějaká data přišla. To znamená, že "Vaše" hlavní starost je, data z ring bufferu pokud možno rychle někam odklidit, protože síťovka na Vás dlouho čekat nebude (pokud Vás v kroužku "doběhne", tak nevyzvednuté pakety přepíše, nebo se zastaví a další přišedší pakety začne zahazovat). Proč to říkám: protože pokud byste si usmyslel, že odchozí pakety skrz TX DMA budete posílat přímo z "příchozího DMA ring bufferu", abyste ušetřil kopírování, bude Vám vyprazdňování tohoto "bufferu s dvojím využitím" záviset na chování odchozích směrů do jednotlivých TX portů. Jednak by se ten ring buffer uvolňoval "napřeskáčku", druhak tam jaksi není garance, že se konkrétní paket vůbec někdy uvolní. Musel byste nad tím běžet nějaký softwarový "garbage collector" který bude pakety přímo v ring bufferu timeoutovat. Ten ring buffer by musel být veliký a jak by se pakety vyřizovaly "napřeskáčku" tak by "řídnul", jasně měl byste nad ním další spojové seznamy / fronty / indexy apod., ale přesto by Vás základní struktura "spojový seznam" mohla začít omezovat i co do výkonu apod.

Taky stojí za zamyšlení, že jak RX DMA ring buffer tak fronty pro TX DMA tvoří jádra kritických sekcí. Předávají si nad nimi veslo hardware síťovky s kernelem. A páchat nějaký složitý management nad kritickou sekcí s DMA... no nevím.

Přijde mi docela sjízdné, při vybírání paketů z RX DMA ring bufferu rovnou provést forwardovací rozhodnutí (pro nás funkce handle_bridge() zmíněná v literatuře) a na základě zvoleného TX portu provést jednu kopii v RAMce do odpovídající TX fronty. Pokud má forwardovací rozhodnutí deterministickou a dostatečně omezenou dobu provedení, nemusel by to být problém, a možná to přesně takto funguje.

Ještě mám pocit, že "kopie z paměti do paměti" by mohl akcelerovat Intel I/OAT DMA engine. Software jenom staví sg-list a o zbytek se nestará. Tahle fičurka se vyskytuje v "serverových" motherboardech (Xeon CPU) ale tuším jsem to jednou chtěl vyzkoušet a měl jsem dost smíšené výsledky. Na některém HW to nešlo zapnout, nebo to mělo v kernelu nějak omezenou použitelnost pro velmi málo oblastí/driverů apod. Ono i to heslo na wikipedii nad tím v závěru ohrnuje nos.

Ten link na PDF co poslal Honza je zajímavé čtení - ovšem týká se zjevně offloadu "těžšího kalibru", kdy za vhodných okolností je paket switchnut přímo externím switchem (který s linuxovým kernelem na nějaké úrovni symbioticky spolupracuje) tzn. na PCI DMA do+z hostitelské RAM vůbec nemusí dojít. Je zajímavé vědět, že taková jemně vrstvená infrastruktura pro externí offload v kernelu existuje, nicméně bych řekl, že takto postavený hardware je zajímavý hybrid: switch ASIC zjevně s PCI apod. rozhraním k hostitelskému CPU. Toto nevídám moc často. Mnohem běžněji vídám schéma, kdy soběstačná switchovací matice má jeden MAC port vůči hostitelskému management CPU = vlastně VLAN trunk v podobě [S|R|G]MII rozhraní včetně MDIO kanálu. V tom případě se nejedná ani tak o nějaký chytristický offload, jako spíš o externí switchovací matici, kterou standardní Linux na mngt CPU víceméně na dálku konfiguruje :-)


kkt1

  • *****
  • 796
    • Zobrazit profil
Re:Implementácia a náročnosť SW bridge
« Odpověď #5 kdy: 17. 09. 2018, 11:01:49 »
Frantisku, muzu se zeptat jestli mate svuj vlastni generator dlouhych odpovedi nebo pouzivate nejakou externi sluzbu?  ::)  ;)Pisete vzdy zajimave a k veci a strasne moc textu...

Honza

Re:Implementácia a náročnosť SW bridge
« Odpověď #6 kdy: 17. 09. 2018, 18:05:22 »
Frantisku, muzu se zeptat jestli mate svuj vlastni generator dlouhych odpovedi nebo pouzivate nejakou externi sluzbu?  ::)  ;)Pisete vzdy zajimave a k veci a strasne moc textu...

No ale to je prave super, clovek se aspon dozvi neco noveho a ma nad cim premyslet. Za me rozhodne palec nahoru k podobnym postum. A taky chci podekovat, ze s tim prispevovatel da takovou praci.

j

Re:Implementácia a náročnosť SW bridge
« Odpověď #7 kdy: 17. 09. 2018, 18:19:08 »
...
Aniz bych to zkoumal, priklanim se k nazoru ze to proste na jedny strane nalejes do RAM a na druhy to z ni zase naladujes do ty karty.

Principielne bys moh ty data posilat naprimo mezi kartama, jenze to by musely umet prave primo ty karty = predpoklad je mit dve takove, ktere to umi a vzajemne si rozumi. A proc by nekdo neco takovyho vyrabel, kdyz se vyrabi switche.

Pokud si dobre pamatuju, u viceportovych karet s integrovanym switchem (a spravnym modulem) to jede naprimo - ale to je dany spis tim, ze ten modul proste jen nakonfiguruje ten switch. Zas tim prides o moznost do toho provozu na urovni SW zasahovat.

Re:Implementácia a náročnosť SW bridge
« Odpověď #8 kdy: 17. 09. 2018, 20:48:50 »
Frantisku, muzu se zeptat jestli mate svuj vlastni generator dlouhych odpovedi nebo pouzivate nejakou externi sluzbu?  ::)  ;)Pisete vzdy zajimave a k veci a strasne moc textu...

No ale to je prave super, clovek se aspon dozvi neco noveho a ma nad cim premyslet. Za me rozhodne palec nahoru k podobnym postum. A taky chci podekovat, ze s tim prispevovatel da takovou praci.

Pánové už dost, já se tou chválou červenám ;-) Vedle zřejmé grafomanie by se jistě našly i nějaké další diagnózy. A stavu pacienta zrovna neprospívá, že má luštění počítačových hádanek v popisu práce. Ono je otázka, jestli by nebylo přínosnější, kdyby za mnou namísto toho roztržitého luštění a písmáctví zůstávala nějaká hmatatelnější tvorba. Momentálně mi okolnosti nedopřávají delší attention span.

kkt1

  • *****
  • 796
    • Zobrazit profil
Re:Implementácia a náročnosť SW bridge
« Odpověď #9 kdy: 17. 09. 2018, 23:00:57 »
Frantisku, muzu se zeptat jestli mate svuj vlastni generator dlouhych odpovedi nebo pouzivate nejakou externi sluzbu?  ::)  ;)Pisete vzdy zajimave a k veci a strasne moc textu...

No ale to je prave super, clovek se aspon dozvi neco noveho a ma nad cim premyslet. Za me rozhodne palec nahoru k podobnym postum. A taky chci podekovat, ze s tim prispevovatel da takovou praci.
To ano, me to bavi cist, ale je to do diskuse imho dlouhy...

mhi_

Re:Implementácia a náročnosť SW bridge
« Odpověď #10 kdy: 18. 09. 2018, 00:55:42 »
Zrovna jsem o vikendu programoval jednoduchy driver & ICMP/ARP "stack" na RTL8139 (a zkoumal RTL8169). To jsou snad ty nejhloupejsi a nejlevnejsi sitovky na trhu. Funguje to tam tak, ze v sitovce se nastavi kruhovy RX buffer, do ktereho sitovka cpe packety. Co je v bufferu (ne)zpracovane se zjistuje pomoci 2 pointeru (registru). Pri prijmu paketu vyskoci interrupt. Vse funguje pomoci bus-master DMA te sitovky.

Odesilani je trivialni, do registru hodite adresu a delku, sitovka packet odesle a vyhodi interrupt (jsou tam mozne 3 buffery).

Bridge by sel nejlepe s realteky implementovat tak, ze IRQ hned u dalsi sitovky prenastavi TX buffer a necha odesilat paket, tzn. vlastni paket se nemusi ani kopirovat, jen se upravi MAC adresy (u forwardu, u bridge netreba).

V Linuxu to myslim bylo podobne, aktualni stav nevim. Problem tam ale je zbytecna latence pri interruptu (context switch, etc.)

Zajimave by to mohlo byt pokud by se podarilo hacknout firmware nejakych drazsich sitovek (napr. nejake Broadcomy), tam by totiz slo udelat prenos sitovka-sitovka bez toho aby do toho CPU vubec hrabalo.

Mimochodem, s "lepsimi" sitovkami (napr RTL8139C+), ktere umi slozit buffer packetu z vice fragmentu by sel udelat pekny fileserver - pomoci DMA by se nacetla data z disku do RAM a ta by se bez dalsiho kopirovani odesilala nekam dal (vsechny hlavicky az po aplikacni by byly ve dvou fragmentech, treti by obsahoval data, pro kazdy ramec by se jen posunul pointer dat a upravily prislusne hlavicky).

Re:Implementácia a náročnosť SW bridge
« Odpověď #11 kdy: 19. 09. 2018, 08:23:00 »
Bridge by sel nejlepe s realteky implementovat tak, ze IRQ hned u dalsi sitovky prenastavi TX buffer a necha odesilat paket, tzn. vlastni paket se nemusi ani kopirovat, jen se upravi MAC adresy (u forwardu, u bridge netreba).

Taktak... ovšem modulo případně problémy s dostatečně rychlým uvolňováním takto využitého RX bufferu, jak už jsem psal výše. Důsledně vyprazdňovat RX buffer tím, že budu kopírovat do další TX fronty je IMO odolnější proti přetečení (záleží na kapacitě dotyčné TX fronty a algoritmech okolo).

Zajimave by to mohlo byt pokud by se podarilo hacknout firmware nejakych drazsich sitovek (napr. nejake Broadcomy), tam by totiz slo udelat prenos sitovka-sitovka bez toho aby do toho CPU vubec hrabalo.

Ohledně přímého přenosu síťovka-síťovka: pokud by se jednalo o oddělená PCI zařízení, tak by to IMO znamenalo, že by cílová síťovka musela mít svůj interní TX buffer exportovaný na PCI sběrnici jako IOMEM okno = v některém BARu přiřazenou adresu a velikost okna (a tyto parametry reálně "dekódovat"). Zdrojová síťovka by učinila rozhodnutí, kam paket switchnout, a poslala by ho na cíl (k tomu by potřebovala přístup k "forwardovací tabulce").
Nebo by mohla exportovat svůj RX buffer zdrojová síťovka, pokud by někdo druhý (hostitel?) učinil "forwardovací rozhodnutí" a instruoval cílovou síťovku, odkud si má paket "zobnout" :-)

K tomu vysvětlivka: pokud správně rozumím, DMA přenos z periferie do RAM běží na PCI sběrnici pomocí bus-mastering transakce "write memory", kterou iniciuje sama periferie, tzn. cílová adresa v této transakci ukazuje skrz hositelský PCI root bridge do hostitelovy RAM. Zdrojovou adresu PCI transakce nemají, takže data burstového zápisu do paměti můžou na straně zdroje téct z nějakého FIFO bufferu, který ani není zvenčí adresovatelný/viditelný. Analogicky z RAM do PCI periferie opět stačí paměťové okno v hostitelově RAM, periferie pomocí transakce "PCI read memory" zkonzumuje obsah okna do nějakého interního FIFO bufferu. Při komunikaci mezi periferiemi navzájem musí aspoň jedna periferie exportovat IOMEM BAR.

Blahé paměti na ISA sběrnici tuším chyběla "autonomní adresní fáze", a pro nasměrování DMA přenosu do konkrétní oblasti RAM byla třeba spolupráce DMA řadiče v čipsetu hostitelského systému, potažmo konkrétní periferie měla pro sebe trvale vyhrazený DMA kanál atd.

PCčko s ochranou paměti pomocí MMU má tzv. fyzický adresní prostor na adresních vodičích pouzdra CPU, a interně si spravuje jeho mapování na virtuální paměťové prostory (kernel a jednotlivé user-space procesy, bokem do toho vstupuje stránkování, swapáč apod). Adresní prostor sběrnice PCI je teoreticky další, opět nezávislý, adresní prostor. Pokud by se PCI periferie bavily mezi sebou napřímo, budou se bavit v kontextu adresního prostoru PCI sběrnice. Překlad fyzického adresního prostoru hostitele na adresní prostor sběrnice PCI provádí PCI root bridge (AKA root complex AKA host bridge).

Adresy IOMEM oken na PCI (skutečně dekódované PCI periferiemi) tedy nejsou nezbytně shodné s adresami ve fyzickém adresním prostoru CPU. Že to hostitelský systém může zařídit tak, aby adresní prostor PCI byl 1:1 s fyzickým adresním prostorem CPU, to je jiná věc. Není to pravidlem. Potažmo než chcete z hostitelského CPU (klidně z linuxového kernelu) sahat nějakému PCI zařízení do IOMEM okna, musíte zavolat "ioremap" nebo jak se to jmenuje. Dostanete virtuální adresu, která Vám bude v programu fungovat. (Analogickou mapovací funkci umí i v DOSu DPMI extender, ovšem tuším nikoli 16bitový PCI BIOS.) Osobně jsem nikdy neprogramoval PCI DMA, takže si nejsem jistý, co všechno je třeba udělat, aby si periferie mohla sahat do hostitelské RAM - čekal bych tam nějaké "inverzní" mapování/dekódování adres zajištěné PCI root bridgem, možná na tom spolupracují MTRR registry... co já vím.

Matně si vybavuju, že snad PCI sběrnici mělo na přelomu století v backplanu Cisco 7200 series (router) - ale co s čím po té sběrnici komunikovalo, to si netroufám tvrdit. Je fakt, že Cisco je průkopníkem všelijakých offloadů a akcelerací.