helenos-xhci team mailing list archive
-
helenos-xhci team
-
Mailing list archive
-
Message #00017
Re: Odložené zpracování událostí
Zdravím ještě jednou,
nakonec mě Jarda donutil prozkoumat blíže async framework, který mi
poskytl odpověď. Vítězná metoda je 3), ovšem s podporou async
frameworku. Kontext:
Pro ošetření IRQ se použije vlákno aktuálního manažera. Pokud se během
ošetřování vlákno uspí, async framework vytvoří manažera nového, který
čeká na další IRQ / call. Tedy, stačí aby obsluha událostí vypadala
nějak takto:
1) zkopíruj si všechny event TRB, protože v ringu se přepíšou
2) prohlaš, že je obsluha dokončena (posuň ERDP, zapiš EHB, ‥)
3) obsluž eventy
Pokud během 3) dojde k uspání, nový manager obslouží další IRQ, a vyřeší
náš race. Pokud k uspání nedojde, žádný nový fibril se nevytváří,
a všechno je rychlé. To z toho dělá optimální řešení...
ACK?
O.
On 03.10., Ondra Hlavatý wrote:
> Zdravím,
>
> rád bych otevřel otázku, kterou jsme řešili osobně i na slacku,
> aprobral ji i s někým kvalifikovanějším.
>
> V současnosti řešíme problém, že zpracování událostí (např. port status
> change event při připojení zařízení) má vyvolat sérii příkazů, kterým se
> připojené zařízení inicializuje z pohledu HC. Na tyto příkazy je potřeba
> čekat, protože v potvrzující zprávě od HC jsou data, která jsou nadále
> potřeba pro další příkazy. Bohužel, tyto zprávy přichází do stejného
> event ringu, jako samotný port status change event. Nelze tedy obsluhu
> této události provádět z vlákna, ve kterém dochází k obsluze událostí
> o dokončení příkazu.
>
> Nabízí se tedy obsluhu události odložit, a zpracovat v jiném
> threadu/fibrilu. Již je implementováno čekání na dokončení příkazu
> uspáním fibrilu.
>
> Možnosti jsou následující:
>
> 1) Vytvořit thread/fibril pool konstantní velikosti, který bude
> obsluhovat top-half události. Implementace jednoduchá, stačí k tomu
> nějaká fronta, do které zkopírujeme TRB o výsledku eventu. Nevýhodou
> je, že pokud hloubka čekání na jiný výsledek v součtu přesáhne
> velikost poolu, máme tu deadlock. Pokud využijeme thready, pak
> vyžaduje synchronizaci a tím úpravu existujících struktur, aby byly
> thread-safe. Odměnou však bude paralelismus ve zpracování událostí.
>
> 2) Kvůli každému typu eventu vytvořit vlákno, které obsluhuje tento
> kontrétní event. Náladu trochu kazí opět port status change, ve
> kterém je potřeba zrestartovat port, a tedy čekat na další port
> status change. Nicméně tuto situaci lze vyřešit rozdělením
> a zapamatováním stavu u portu. Nevýhoda je jasná, událostí je poměrně
> hodně. Lze se však omezit na "těžkotonážní" události, a tím počet
> vláken zredukovat. Vyžaduje synchronizaci.
>
> 3) Vytvořit fibril pro každou událost tohoto typu, tedy místo okamžitého
> řešení události vytvořit fibril, který ji obslouží. Události jsou
> označeny za vyřešené okamžitě, fibrily se pak budou postupně
> probouzet a blokovat na čekání. Tím se uvolní prostor pro obsluhu
> dalších událostí v původním fibrilu. Jednoduchá implementace. Můžeme
> si však dovolit vytvářet fibril při každé významnější události?
> Výhodou je, že toto řešení nevyžaduje synchronizaci, dokud se fibrily
> přeplánovávají pouze explicitně.
>
> 4) Inspirovat se tím, co dělá například Fuchsia, a v podstatě
> reimplementovat lightweight fibrily - mít frontu handlerů, které se
> postupně spouští, ověří podmínky pro běh, a pokud nejsou splněny,
> naplánují se na konec fronty. Fronta se spouští, když dojde k eventu.
> Nevýhodou je, že kód pro obsluhu událostí se musí rozdělit do fází,
> které se plánují do front. V zásadě se pak musí místo
> synchronizačních primitiv používat odplánování, a tím si primitiva
> implementovat pokaždé "ručně". Ale je to dobré řešení z hlediska výkonu.
>
> 5) Řešit konkrétně port status change event tím, že vytvoříme fibril pro
> každý obsluhovaný port. To významně usnadní psaní kódu pro tuto část
> roothubu - celý stavový automat pak lze napsat jako jednu funkci,
> která v nečinnosti blokuje, a stav si udržuje implicitně stavem
> fibrilu. Nevýhodou je však menší robustnost - možná nekonzistence
> stavu automatu a skutečného stavu portu. Pokud si stav zjišťujeme
> z HW při začátku obsluhy, máme větší šanci, že se tomuto vyhneme.
>
> Přes snahu se mi nepodařilo vyluštit, jak tento problém řeší v Linuxu.
> Ostatní kernely jsem zatím nestudoval.
>
> Jaké jsou vaše názory, jak se se situací vypořádat?
>
> Ondra
>
> --
> Mailing list: https://launchpad.net/~helenos-xhci
> Post to : helenos-xhci@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~helenos-xhci
> More help : https://help.launchpad.net/ListHelp
Follow ups
References