Sdílet prostřednictvím


Použití přímých vstupně-výstupních operací s PIO

Ovladač, který používá programované vstupně-výstupní operace (PIO) místo DMA, musí dvakrát namapovat vyrovnávací paměti uživatelského prostoru do rozsahu adres systémového prostoru. Následující obrázek znázorňuje, jak správce vstupně-výstupních operací nastaví požadavek IRP_MJ_READ na operaci převodu PIO, která používá přímé vstupně-výstupní operace.

diagram znázorňující přímé vstupně-výstupní operace pro zařízení, která používají pio

Obrázek znázorňuje, jak zařízení, které používá PIO, zpracovává stejnou úlohu.

  1. Některé rozsahy virtuálních adres uživatelského prostoru představují vyrovnávací paměť aktuálního vlákna a obsah této vyrovnávací paměti může být skutečně uložen na některém počtu fyzicky nesouvislých stránek. Pokud je délka vyrovnávací paměti nenulová, správce vstupně-výstupních operací vytvoří MDL pro popis této vyrovnávací paměti.

  2. Správce vstupů/výstupů (I/O) zpracovává požadavek aktuálního vlákna na čtení, přičemž vlákno předává rozsah virtuálních adres uživatelského prostoru, které představují vyrovnávací paměť.

  3. Správce vstupně-výstupních operací nebo FSD kontroluje dostupnost vyrovnávací paměti zadané uživatelem. Pokud správce vstupně-výstupních operací vytvořil MDL, volá MmProbeAndLockPages s MDL, který určuje rozsah virtuálních adres pro vyrovnávací paměť uživatele. MmProbeAndLockPages také vyplní odpovídající rozsah fyzických adres v MDL.

  4. Správce vstupně-výstupních operací poskytuje ukazatel na MDL (MdlAddress) v protokolu IRP, který požaduje operaci přenosu. Do té doby, než správce vstupně-výstupních operací nebo systém souborů zavolá MmUnlockPages po dokončení práce ovladače, zůstávají fyzické stránky popsané v MDL uzamčené a přiřazené k vyrovnávací paměti. Virtuální adresy v takovém MDL se ale můžou stát neviditelnými (a neplatnými) i před odesláním protokolu IRP na ovladač zařízení nebo do jakéhokoli zprostředkujícího ovladače, který může být vrstvený nad ovladačem zařízení.

  5. Pokud ovladač vyžaduje systémové (virtuální) adresy, volá ovladač MmGetSystemAddressForMdlSafe s ukazatelem MdlAddress IRP za účelem dvojitého mapování adres ve virtuálním uživatelském prostoru v MDL na rozsah adres v systémovém prostoru. Na obrázku výše představuje AliasBuff MDL, který popisuje dvojitě mapované adresy.

  6. Ovladač používá rozsah virtuálních adres systémového prostoru z dvakrát namapovaného MDL (AliasBuff) k načtení dat do paměti.

Po dokončení IRP voláním IoCompleteRequest správce vstupně-výstupních operací nebo systému souborů uvolní doubly mapovaný rozsah systémového prostoru MDL, pokud ovladač s názvem MmGetSystemAddressForMdlSafe. Správce vstupně-výstupních operací nebo systém souborů odemkne stránky popsané v MDL a odstraní MDL a IRP jménem ovladače. Kvůli lepšímu výkonu by se ovladače měly vyhnout podrobnému mapování fyzických adres MDL na systémový prostor, jak je popsáno v kroku 3, pokud nesmí používat virtuální adresy. Tím se zbytečně používají systémové položky stránkovací tabulky a můžou snížit výkon i škálovatelnost ovladače. Kromě toho může systém selhat, pokud dojde k nedostatku položek stránkovací tabulky, protože většina starších ovladačů tuto situaci nedokáže zpracovat.

Vyrovnávací paměti aktuálního uživatelského vlákna a samotné vlákno je zaručeno, že budou rezidentní ve fyzické paměti pouze v době, kdy je toto vlákno aktuální. Pro vlákno zobrazené na předchozím obrázku může být obsah vyrovnávací paměti uživatele stránkován do sekundárního úložiště, zatímco jsou spuštěna vlákna jiného procesu. Při spuštění vlákna jiného procesu je možné přepsat systémovou fyzickou paměť vyrovnávací paměti požadovaného vlákna, pokud správce paměti nezamkl a zachoval odpovídající fyzické stránky, které obsahují vyrovnávací paměť původního vlákna.

Virtuální adresy původního vlákna pro vyrovnávací paměť však nezůstanou viditelné, zatímco jiné vlákno je aktuální, i když správce paměti zachová fyzické stránky vyrovnávací paměti. Ovladače proto nemůžou pro přístup k paměti použít virtuální adresu vrácenou nástrojem MmGetMdlVirtualAddress . Volající této rutiny musí předat své výsledky MapTransfer (spolu s ukazatelem MdlAddress IRP), aby bylo možné přenášet data pomocí systému založeného na paketech nebo sběrnice DMA.