Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ostrożność
W przypadku procesorów Arm i Arm64 zdecydowanie zalecamy, aby twórcy/drajwerzy NDIS używali składników WDF DMA lub WDM DMA zamiast NDIS Scatter/Gather DMA.
Aby uzyskać więcej informacji na temat usługi WDF DMA, zobacz Obsługa operacji DMA w sterownikach KMDF.
Aby uzyskać więcej informacji o programie WDM DMA, zobacz tematy podrzędne związane z programem DMA Zarządzanie danymi wejściowymi/wyjściowymi sterowników.
Sterowniki miniportu NDIS mogą używać metody Scatter/Gather DMA (SGDMA) do transferu danych między kartą sieciową a pamięcią systemową. Pomyślny transfer DMA wymaga, aby fizyczny adres danych mieścił się w zakresie adresów obsługiwanym przez kartę sieciową. Hal udostępnia mechanizm umożliwiający sterownikom uzyskanie listy fizycznych adresów dla łańcucha MDL i, jeśli to konieczne, przeprowadzi dwukrotne buforowanie danych do fizycznego zakresu adresów.
W wersjach NDIS wcześniejszych niż NDIS 6.0 obsługa SGDMA w sterownikach miniportu i NDIS jest ograniczona w niektórych kwestiach, a w szczególności nie działa dobrze w scenariuszu wysyłania wielopakietowego. Obsługa NDIS 6.0 SGDMA pozwala przezwyciężyć te ograniczenia, zapewniając jednocześnie prosty interfejs dla sterowników miniportów.
Historia NDIS SGDMA
W wersjach NDIS wcześniejszych niż NDIS 6.0 NDIS uzyskuje listę rozproszenia i zbierania (SG) dla każdego pakietu przed wysłaniem pakietu do sterownika miniportowego. NDIS obsługuje również przypadek, w którym oryginalna próba uzyskania listy SG kończy się niepowodzeniem z powodu nadmiernej fragmentacji. W takim przypadku usługa NDIS dwukrotnie buforuje pakiet do ciągłego buforu i próbuje ponownie. Hal może również buforować dane podwójnie do adresu fizycznego obsługiwanego przez kartę sieciową, jeśli na przykład fizyczny adres danych przekracza maksymalną 32-bitową wartość, a karta sieciowa nie obsługuje 64-bitowego DMA.
Aby uniknąć sytuacji zakleszczenia, NDIS uzyskuje listę SG dla pakietu i wysyła jeden pakiet naraz. Jeśli usługa NDIS próbuje mapować wszystkie pakiety przed wysłaniem ich do sterownika miniportu, system może zabraknąć zasobów. W takim przypadku usługa NDIS będzie czekać na udostępnienie rejestrów map, podczas gdy niektóre rejestry map są zablokowane dla pakietów, które nie zostały wysłane. Nie można ponownie używać zablokowanych pakietów.
Takie podejście do obsługi SGDMA ma następujące ograniczenia:
Ponieważ pakiet jest mapowany przed przejściem do sterownika miniportu, sterownik nie może zoptymalizować pod kątem małych pakietów lub pakietów, które są zbyt pofragmentowane. Sterownik miniportu nie może buforować pakietu podwójnie do znanego adresu fizycznego.
Nie ma gwarancji, że tablica adresów fizycznych przekazana przez NDIS do sterownika miniportu odpowiada wirtualnemu adresowi oryginalnych danych. W związku z tym, jeśli sterownik zmieni dane pod adresem wirtualnym w łańcuchu MDL przed ich wysłaniem, modyfikacje wprowadzone w danych nie zostaną odzwierciedlone w danych w adresach fizycznych. W takim przypadku karta sieciowa wysyła niezmodyfikowane dane.
Usługa NDIS jest ograniczona do wysyłania jednego pakietu naraz, aby uniknąć zakleszczenia z powodu problemów z zasobami. Nie jest to tak wydajne, jak wysyłanie wielu pakietów.
Ponieważ NDIS nie może określić możliwości transmisji sterowników miniportu, nie może wstępnie przydzielić pamięci dla bufora listy SG. W związku z tym usługa NDIS musi przydzielić niezbędną pamięć w czasie działania. Nie jest to tak wydajne, jak wstępne przydzielanie magazynu.
Funkcje HAL, które przydzielają listę SG, powinny być wywoływane przy IRQL = DISPATCH_LEVEL. Usługa NDIS nie ma bieżących informacji o poziomie IRQL, więc musi ustawić IRQL na DISPATCH_LEVEL, nawet jeśli jest już na DISPATCH_LEVEL. Nie jest to wydajne, jeśli poziom IRQL jest już na DISPATCH_LEVEL.
Zalety obsługi NDIS SGDMA
W interfejsie NDIS 6.0 i nowszym SGDMA usługa NDIS nie mapuje buforu danych przed wysłaniem go do sterownika miniportu. Zamiast tego usługa NDIS udostępnia interfejs sterownika do mapowania danych sieciowych.
Takie podejście daje następujące korzyści:
Ponieważ usługa NDIS udostępnia interfejs HAL do mapowania danych sieciowych, sterowniki miniportów są chronione przez NDIS przed złożonością i szczegółami procesu mapowania.
Sterowniki Miniport mają dostęp do danych przed zmapowaniem. W związku z tym wszelkie zmiany wprowadzone w oryginalnych danych są odzwierciedlane w danych reprezentowanych przez listę SG, nawet jeśli dane są buforowane dwukrotnie przez NDIS lub HAL.
Sterowniki miniportów mogą zoptymalizować transmisję małych lub wysoce pofragmentowanych pakietów, kopiując je do buforu wstępnie przydzielonego ze znanym adresem fizycznym. Takie podejście pozwala uniknąć mapowania, które nie jest wymagane, a tym samym poprawia wydajność systemu.
NDIS może bezpiecznie wysyłać wiele buforów do sterownika miniportu. Skutkuje to mniejszą liczbą wywołań sterowników miniportu, co w rezultacie poprawia wydajność systemu.
Sterowniki miniportu mogą wstępnie przydzielić pamięć dla listy SG w ramach bloków deskryptora transmisji. W związku z tym sterowniki NDIS lub miniport nie muszą przydzielać pamięci dla list SG podczas działania.
Ponieważ sterowniki miniportu mogą działać na poziomie IRQL = DISPATCH_LEVEL, mogą unikać niepotrzebnych wywołań do podnoszenia IRQL do DISPATCH_LEVEL. Na przykład, ponieważ ukończenie wysyłania odbywa się w kontekście przerwania DPC, sterowniki miniportu mogą zwolnić listę SG bez podnoszenia IRQL.
Rejestrowanie i wyrejestrowanie kanałów DMA
Sterownik miniportu NDIS wywołuje funkcję NdisMRegisterScatterGatherDma z funkcji MiniportInitializeEx, aby zarejestrować kanał DMA w NDIS.
Sterownik miniportu przekazuje opis DMA do NdisMRegisterScatterGatherDma w parametrze DmaDescription. NdisMRegisterScatterGatherDma zwraca rozmiar buforu, który powinien być wystarczająco duży, aby pomieścić listę rozproszenia/zebrania. Sterowniki miniportu powinny używać tego rozmiaru, aby wstępnie przydzielić pamięć na listy scatter/gather.
Sterownik miniportu przekazuje również NdisMRegisterScatterGatherDma punkty wejścia dla funkcji MiniportXxx, które NDIS wywołuje do przetwarzania listy rozproszenia/zebrania. NDIS wywołuje funkcję miniportu MiniportProcessSGList po utworzeniu listy rozrzucania/zbiegania dla buforu przez HAL. NdisMRegisterScatterGatherDma dostarcza uchwyt w parametrze pNdisMiniportDmaHandle, którego sterownik miniportu musi używać w kolejnych wywołaniach funkcji DMA NDIS typu wieloblokowego.
Sterownik miniportu NDIS wywołuje funkcję NdisMDeregisterScatterGatherDma z funkcji MiniportHaltEx, aby zwolnić zasoby scatter/gather DMA.
Przydzielanie i zwalnianie list Scatter/Gather
Sterownik miniportu NDIS wywołuje funkcję NdisMAllocateNetBufferSGList w funkcji MiniportSendNetBufferLists. Sterownik miniportu wywołuje NdisMAllocateNetBufferSGList raz dla każdej struktury NET_BUFFER, którą musi zmapować. Po udostępnieniu zasobów i przygotowaniu listy SG, NDIS wywołuje funkcję sterownika MiniportProcessSGList. NDIS może wywołać MiniportProcessSGList przed lub po tym, jak wywołanie sterownika miniportu do NdisMAllocateNetBufferSGList zostanie zwrócone.
Aby zwiększyć wydajność systemu, lista scatter/gather jest generowana na podstawie danych sieciowych, zaczynając od początku listy MDL określonej w składowej CurrentMdl powiązanej struktury NET_BUFFER_DATA. Początek danych sieciowych na liście SG jest przesunięty względem początku listy SG o wartość określoną w członie CurrentMdlOffset w strukturze NET_BUFFER_DATA.
Podczas obsługi DPC w związku z przerwaniem pełnego wysyłania, gdy sterownik miniportu nie potrzebuje już listy SG, powinien on wywołać funkcję NdisMFreeNetBufferSGList, aby zwolnić listę SG.
Uwaga Nie wywołuj NdisMFreeNetBufferSGList, gdy sterownik lub sprzęt nadal korzysta z pamięci opisanej przez strukturę NET_BUFFER skojarzoną z listą rozproszenia/zbierania.
Przed uzyskaniem dostępu do odebranych danych sterowniki miniportu muszą wywołać NdisMFreeNetBufferSGList, aby opróżnić pamięć podręczną.