← Back to team overview

helenos-xhci team mailing list archive

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