Odciążanie zlecania łączenia segmentów odbieranych UDP (URO)
Począwszy od systemu Windows 11 w wersji 24H2, funkcja URO (UDP receive segment coalescing offload) umożliwia kartom sieciowym łączenie segmentów odbiorczych UDP. Karty sieciowe mogą łączyć datagramy UDP z tego samego przepływu, które pasują do zestawu reguł, w logicznie ciągły bufor. Te połączone datagramy są następnie przekazywane stosowi sieciowemu systemu Windows jako jeden duży pakiet.
Łączenie datagramów UDP zmniejsza koszt CPU do przetwarzania pakietów w przepływach o wysokiej przepustowości, co skutkuje większą przepustowością i mniejszą liczbą cykli na bajt.
W poniższych sekcjach opisano reguły łączenia pakietów UDP i sposobu pisania sterownika miniportu URO.
- Reguły łączenia pakietów UDP
- napisz sterownik miniportu URO
- Zagadnienia dotyczące programowania sterowników URO
Reguły łączenia pakietów UDP
Łączenie URO można podjąć tylko na pakietach spełniających wszystkie następujące kryteria:
-
IpHeader.Version
jest identyczna dla wszystkich pakietów. -
IpHeader.SourceAddress
iIpHeader.DestinationAddress
są identyczne dla wszystkich pakietów. -
UdpHeader.SourcePort
iUdpHeader.DestinationPort
są identyczne dla wszystkich pakietów. -
UdpHeader.Length
jest identyczne dla wszystkich pakietów, z wyjątkiem ostatniego pakietu, który może być mniejszy. -
UdpHeader.Length
musi być niezerowa. -
UdpHeader.Checksum
, jeśli niezerowa, musi być poprawna we wszystkich pakietach. Oznacza to, że odbieranie sumy kontrolnej musi zweryfikować pakiet. -
Layer 2 headers
musi być identyczne dla wszystkich pakietów.
Jeśli pakiety mają protokół IPv4, muszą również spełniać następujące kryteria:
-
IPv4Header.Protocol
== 17 (UDP) dla wszystkich pakietów. -
EthernetHeader.EtherType
== 0x0800 dla wszystkich pakietów. -
IPv4Header.HeaderChecksum
odebranych pakietów musi być poprawne. Oznacza to, że odciążanie sumy kontrolnej musi zweryfikować nagłówek. -
IPv4Header.HeaderLength
== 5 (brak nagłówków opcji IPv4) dla wszystkich pakietów. -
IPv4Header.ToS
jest identyczna dla wszystkich pakietów. -
IPv4Header.ECN
jest identyczna dla wszystkich pakietów. -
IPv4Header.DontFragment
jest identyczna dla wszystkich pakietów. -
IPv4Header.TTL
jest identyczna dla wszystkich pakietów. -
IPv4Header.TotalLength
==UdpHeader.Length
* + length(IPv4Header
) dla wszystkich pakietów.
Jeśli pakiety są IPv6, muszą również spełniać następujące kryteria:
-
IPv6Header.NextHeader
== 17 (UDP) dla wszystkich pakietów (bez nagłówków rozszerzeń). -
EthernetHeader.EtherType
== 0x86dd (IPv6) dla wszystkich pakietów. -
IPv6Header.TrafficClass
iIPv6Header.ECN
są identyczne dla wszystkich pakietów. -
IPv6Header.FlowLabel
jest identyczna dla wszystkich pakietów. -
IPv6Header.HopLimit
jest identyczna dla wszystkich pakietów. -
IPv6Header.PayloadLength
==UdpHeader.Length
dla wszystkich pakietów.
Struktura pakietów URO
Wynikowa pojedyncza połączona jednostka (SCU) musi mieć jeden nagłówek IP i nagłówek UDP, a następnie ładunek UDP dla wszystkich połączonych datagramów, które są ze sobą połączone.
Wskazania URO muszą ustawić pole IPv4Header.TotalLength
na łączną długość SCU, pole IPv6Header.PayloadLength
na długość ładunku UDP, a pole UdpHeader.Length
na długość skoordynowanych ładunków.
Jeśli nagłówki warstwy 2 (L2) znajdują się w scalonych datagramach, SCU musi zawierać prawidłowy nagłówek L2. Nagłówek L2 w SCU musi przypominać nagłówek L2 z zebranych datagramów.
Sprawdzanie poprawności sumy kontrolnej i indykacja
Wskazania URO muszą ustawić pola IPv4Header.HeaderChecksum
i UdpHeader.Checksum
na wartość zero oraz wypełnić informacje o pozapasmowym odciążaniu sumy kontrolnej w SCU, wskazujące na powodzenie sum kontrolnych IPv4 i UDP.
Pakiet, spełniający wszystkie warunki do połączenia, ale którego walidacja sumy kontrolnej kończy się niepowodzeniem, musi być wskazany oddzielnie. Pakiety odebrane po nim nie powinny być łączone z pakietami odebranymi przed nim.
Załóżmy na przykład, że pakiety 1, 2, 3, 4 i 5 są odbierane z tego samego przepływu, ale pakiet 3 kończy się niepowodzeniem weryfikacji sumy kontrolnej. Pakiety 1 i 2 mogą być scalone, a pakiety 4 i 5 mogą być scalone, ale pakiet 3 nie może być scalony ani z jednym, ani z drugim SCU. Pakiety 1 i 2 nie mogą być połączone razem z pakietami 4 i 5. Pakiet 2 jest ostatnim pakietem w scU, a pakiet 4 uruchamia nową jednostkę SCU. Ponadto należy wskazać jednostki SCU zawierające pakiety 1 i 2, zanim zostanie wskazany pakiet 3, a pakiet 3 należy wskazać przed wskazaniem SCU zawierającego pakiety 4 i 5.
Łączenie pakietów i separacja przepływów
Pakiety danych z wielu przepływów można połączyć równolegle, jeśli pozwala na to sprzęt i pamięć. Pakiety z różnych strumieni nie mogą być ze sobą łączone.
Pakiety odbierane przeplatane z wielu strumieni mogą być rozdzielone i scalone z odpowiednimi przepływami. Na przykład, biorąc pod uwagę przepływy A, B i C, jeśli pakiety docierają w kolejności A, A, B, C, B, A, pakiety z przepływu A można połączyć do AAA, a pakiety z przepływu B można połączyć w BB, podczas gdy pakiet z przepływu C może być wskazany normalnie lub połączony z oczekującym SCU z przepływu C.
Pakiety w danym przepływie nie mogą być przestawiane względem siebie. Na przykład pakiety z przepływu A muszą być łączone w kolejności odbioru, niezależnie od pakietów z przepływów B i C odebranych pomiędzy.
Słowo kluczowe INF do kontrolowania URO
Następujące słowo kluczowe może służyć do włączania/wyłączania URO z ustawieniem klucza rejestru:
*UdpRsc
Ustandaryzowane słowa kluczowe INF mają następujące atrybuty:
SubkeyName: nazwa słowa kluczowego, które należy określić w pliku INF i który pojawia się w rejestrze.
ParamDesc: tekst wyświetlany skojarzony z nazwą podklucza.
wartość: wartość całkowita wyliczenia skojarzona z każdą opcją na liście. Ta wartość jest przechowywana w NDI\params\SubkeyName\Value.
EnumDesc: tekst wyświetlany skojarzony z każdą wartością wyświetlaną w menu.
Wartość domyślna: domyślna wartość dla menu.
Nazwa podklucza | ParamDesc | Wartość | OpisWyliczenia |
---|---|---|---|
*UdpRsc |
URO | 0 | Niepełnosprawny |
1 (ustawienie domyślne) | Włączone |
Aby uzyskać więcej informacji dotyczące używania słów kluczowych wyliczenia, zobacz Słowa kluczowe wyliczenia.
Napisać sterownik miniportu URO
Począwszy od NDIS 6.89, interfejs NDIS dla URO ułatwia komunikację między tcp/IP i sterownikiem miniport NDIS.
Zdolność do raportowania URO
Sterownik miniportu ogłasza wsparcie URO w składowej UdpRsc
struktury NDIS_OFFLOAD, którą przekazuje do funkcji NdisMSetMiniportAttributes.
Możliwość URO zapytań
Aby sprawdzić, czy sterownik miniportu obsługuje URO, sterowniki NDIS i inne aplikacje mogą wykonywać zapytania dotyczące identyfikatora OID OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, który zwraca strukturę NDIS_OFFLOAD
.
Sprawdź stan URO
Aby określić bieżący stan URO, sterowniki NDIS i inne aplikacje mogą wysyłać zapytania dotyczące żądania identyfikatora OID OID_TCP_OFFLOAD_CURRENT_CONFIG. NDIS obsługuje ten OID i nie przekazuje go do miniportu.
Zmienianie stanu URO
URO można włączyć lub wyłączyć, wysyłając żądanie OID OID_TCP_OFFLOAD_PARAMETERS. Ten identyfikator OID używa struktury NDIS_OFFLOAD_PARAMETERS. W tej strukturze element członkowski UdpRsc.Enabled
może mieć następujące wartości:
Wartość | Znaczenie |
---|---|
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_NO_CHANGE 0 |
Sterownik miniportu nie powinien zmieniać bieżącego ustawienia. |
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED 1 |
URO jest wyłączone. |
Parametry odciążenia NDIS - UDP RSC włączone 2 |
URO jest włączone. |
Gdy sterownik przetwarza żądanie identyfikatora OID OID_TCP_OFFLOAD_PARAMETERS z ustawioną flagą NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED
, karta sieciowa musi czekać z ukończeniem żądania, dopóki nie zostaną wskazane wszystkie istniejące scalone segmenty i oczekujące wskazania URO. To zapewnia synchronizację zdarzeń włączania i wyłączania URO między składnikami NDIS.
Gdy sterownik miniportu przetwarza zapytanie OID OID_TCP_OFFLOAD_PARAMETERS, musi wydać NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG indykację z zaktualizowanym stanem odciążania.
Flaga NDIS_OFFLOAD_PARAMETERS_SKIP_REGISTRY_UPDATE
w NDIS_OFFLOAD_PARAMETERS umożliwia wyłączenie URO tylko w czasie działania. Zmiany wprowadzone za pomocą tej flagi nie są zapisywane w rejestrze.
Rezygnacja z URO w standardzie NDIS 6.89 i nowszych wersjach
Sterowniki przeznaczone dla NDIS 6.89 i nowszych powinny rozumieć pakiety URO i obsługiwać je płynnie. Aby zrezygnować z URO:
- Sterowniki filtru uproszczonego (LWF) ustawiają flagę
NDIS_FILTER_DRIVER_UDP_RSC_NOT_SUPPORTED
w strukturze NDIS_FILTER_DRIVER_CHARACTERISTICS. - Sterowniki protokołów ustawiają flagę
NDIS_PROTOCOL_DRIVER_UDP_RSC_NOT_SUPPORTED
w strukturze NDIS_PROTOCOL_DRIVER_CHARACTERISTICS.
Takie podejście zapewnia, że składniki, które nie są zaznajomione z URO, nie otrzymują URO NBL. NDIS wyłącza URO na miniportie podczas łączenia, jeśli jest obecny sterownik LWF lub protokołowy, który nie obsługuje URO.
Zagadnienia dotyczące programowania dla sterowników URO
Podczas implementowania sterownika miniportu obsługującego URO należy wziąć pod uwagę następujące problemy.
Winsock URO API
Aby uzyskać informacje na temat interfejsu API URO Winsock, zobacz opcje gniazda IPPROTO_UDP . Zapoznaj się z informacjami na temat UDP_RECV_MAX_COALESCED_SIZE
i UDP_COALESCED_INFO
.
Aktualizacje stosu TCP/IP systemu Windows
Transport protokołu TCP/IP firmy Microsoft umożliwia URO podczas wiązania z NDIS, chyba że konfiguracja to uniemożliwia.
Wywołania WFP mogą używać FWP_CALLOUT_FLAG_ALLOW_URO
w FWPS_CALLOUT2 do reklamowania swojego wsparcia dla URO. Jeśli niezgodne wywołanie WFP jest zarejestrowane w warstwie wrażliwej na URO, system operacyjny wyłącza funkcję URO, gdy wywołanie jest zarejestrowane.
Jeśli gniazdo zdecyduje się na URO z maksymalnym rozmiarem ściętym większym lub równym rozmiarowi odciążania sprzętu, stos dostarczy NBLs ze sprzętu niezmodyfikowanego do gniazda. Jeśli gniazdo zdecyduje się na mniejszy maksymalny rozmiar kumulacji, stos rozdziela kumulowany odbiór na mniejsze rozmiary dla tego gniazda.
Jeśli gniazdo nie wyrazi zgody na URO, stos przegrupowuje odebrane dane dla tego gniazda. W przypadku braku sprzętowej opcji URO, istniejąca funkcja URO w oprogramowaniu jest nadal dostępna.