← Back to team overview

helenos-nicf team mailing list archive

Re: [Branch ~helenos-nicf/helenos/nicf] Rev 837: Ticket 56 (DMA reference counting) fixed

 

Ahoj,

toto řešení by asi chtělo trochu probrat, mně osobně se příliš nelíbí. Jedním z cílů projektu je i psaní co nejméně kódu v kernelu a zavádění dalšího callbacku do as_area backendu mi přijde proti této myšlence (naopak je to poměrně výrazný zásah do kernelu). Také jsem trochu prozkoumal práce s as_area callbacky v kernelu a narazil na problematická místa u direct_backendu.

Možná něco přehlížím, ale počítání referencí na celé as_area mi přijde naprosto dostačující (a to dělá kernel zcela automaticky pomocí sh_info->refcount), zvyšování počtu referenci na konkrétní stránku, resp. blok DMA paměti, může být ošetřeno v obsluze page_fault při vytváření mapování, snížení pak v obsluze frame_free - stejně jako to je v backend_anon.

Kopírování tabulky mapování stránek při sdílení je u DMA paměti vcelku zbytečné - u backend_anon to má to opodstatnění, že stránky jsou alokovány za běhu a tudíž page_fault procesu, který si nasdílel paměť, musí najít adresu fyzické stránky v pagemap majitele paměti, popř. být schopen předat informaci o nově naalokovaném rámci (je-li první, kdo na odpovídající adresu sáhl). U direct backendu je veškerá informace nutná ke zjištění fyzické adresy obsažena už v backend_data, tudíž se informace jen bez užitku duplikuje. Navíc v as_area_destroy se volá sh_remove_reference, která (v případě, že počet referencí na sh_area klesne na 0 == area už nikdo nevlastní) zavolá frame_free na všechny záznamy v sh_info->pagemap, což IMO způsobí buď situaci, že DMA struktury kernelu budou mít stránky za stále alokované (ačkoliv už na ně bylo zavoláno frame_free z sh_remove_reference) a nebo se frame_free zavolá na stránku dvakrát (jednou z dma_merge_free_block a jednou v sh_remove_reference).

Dle mého soudu je lepším řešením:
- v obsluze page_fault přidat mapování a zvýšit počet referencí na frame
    - v obsluze frame_free snížit počet referencí na frame
- sh_info->pagemap zcela ignorovat (kvůli zabránění volání frame_free mimo DMA)

Akorát tu je jeden problém - musí se předejít situaci, kdy majitel sdílené paměti na ni ještě nesáhl (=> reference se pro něj nezvýšila), ale někdo ji nasdílel a pak skončil. Tomu lze předejít například tím, že v obsluze backend->create se rovnou vytvoří mapování na celé area => reference se zvýší na 1 kvůli majiteli, resp. chápu-li DMA alokátor dobře, počet referencí je na celou alokovanou oblast => stačí vynutit vložení na první stránku oblasti (v backend_anon je tento problém vyřešen tím, že se při vložení mapování do sh_info->pagemap zvýší počet referencí na frame (právě tato je párována pomocí frame_free v sh_remove_reference v případě dealokace sh_info).

Zdá se mi tedy, že odpovídajícího výsledku lze dosáhnout i za použití stávajících callbacků (a složitost takové implementace mi přijde podobná) a není vůbec potřeba zavádět nějaký nový. Pokud jsem něco přehlédl či špatně pochopil, opravte mne.

Jirka




Follow ups