Sdílet prostřednictvím


Správa vyrovnávací paměti síťových dat

Správa vyrovnávací paměti je funkce, která umožňuje klientským ovladačům síťové karty (NIC) a operačnímu systému spolupracovat při přidělování vyrovnávacích pamětí dat paketů z systémové paměti pro datové cesty přenosu (Tx) a příjmu dat (Rx). To může vést k rychlejšímu výkonu síťové karty, snadnější správě doby života paměti pro klientský ovladač síťové karty a větší kontrolu nad pamětí systému.

Výhody správy vyrovnávacích pamětí v NetAdapterCx

Volba místa, kde jsou vyrovnávací paměti dat přiděleny ze systémové paměti pro obsahy paketů, je zásadní pro výkon datové cesty. V netAdapterCx je model správy vyrovnávací paměti optimalizovaný pro hardware síťových adaptérů podporujících DMA a nejlepším způsobem, jak ho klientské ovladače využít, je umožnit systému přidělit vyrovnávací paměti dat jejich jménem pro cesty Tx i Rx. Klientské ovladače ale mohou stále ovlivnit, kde a jak systém přiděluje vyrovnávací paměti dat, aby je snadno využíval klientský hardware.

Představte si například typickou síťovou kartu podporující DMA. Tento přístup má následující výhody:

  1. Datové vyrovnávací paměti jsou přidělovány a uvolňovány systémem. Klientský ovladač je proto uvolněn z zátěže správy životnosti paměti.
  2. Systém zajistí, aby přidělené vyrovnávací paměti dat byly pro hardware síťové karty připravené na DMA na základě funkcí deklarovaných klientským ovladačem. Poté může klientský ovladač snadno nastavit datové vyrovnávací paměti do svého hardwaru as-is, aniž by musel provádět jakékoli další operace mapování DMA.
  3. Systém může vzít v úvahu potřeby aplikací vyšší vrstvy při přidělování vyrovnávacích pamětí dat, takže se může rozhodnout optimalizovat pro globální komplexní výkon místo pouze místního koncového výkonu.

U síťových adaptérů, které nejsou podporující DMA, jako je síťový klíč založený na USB nebo pro jiné pokročilé/softwarové síťové adaptéry, poskytuje model správy vyrovnávací paměti také možnost zcela ponechat správu vyrovnávací paměti pro klientský ovladač.

Jak efektivně využívat správu bufferů

Důležitý

Pokud je váš hardware s podporou DMA, budete muset před nastavením možností Rx a Tx vytvořit objekt WDFDMAENABLER. Při konfiguraci objektu WDFDMAENABLER se strukturou WDF_DMA_ENABLER_CONFIG nezapomeňte nastavit WdmDmaVersionOverride člena na 3 pro určení verze DMA 3.

Pokud se chcete přihlásit ke správě vyrovnávací paměti, postupujte takto:

  1. Při spuštění vašeho síťového adaptéru, ale před voláním NetAdapterStart, sdělte systému možnosti a omezení vyrovnávací paměti vašeho hardwaru pomocí datové struktury NET_ADAPTER_RX_CAPABILITIES a NET_ADAPTER_TX_CAPABILITIES pro cestu Rx a Tx.
  2. Inicializace dvou struktur schopností voláním jedné z inicializačních funkcí. Například klientský ovladač síťové karty podporující DMA by použil NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA a NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA k deklarování svých hardwarových schopností DMA a aby systému poskytl pokyn k plné správě datových vyrovnávacích pamětí jeho jménem.
  3. Předejte inicializované struktury Tx a Rx do metody NetAdapterSetDatapathCapabilities.

Příklad

Následující příklad ukazuje základní kroky popsané v předchozí části, jak začít používat správce vyrovnávací paměti v klientském ovladači síťové karty. Příklad používá DMA pro Tx i Rx, takže dříve vytvořil objekt WDFDMAENABLER, který byl uložen v kontextovém prostoru zařízení.

Všimněte si, že příklad také nastaví některé indikace o fragmentových vyrovnávacích pamětech po úvodní inicializaci jeho struktury schopností Tx a Rx. Tyto rady mohou být použity ovladači NetAdapterCx a ovladači protokolu ke zlepšení výkonu.

Zpracování chyb bylo vynecháno pro lepší přehlednost.

VOID
MyAdapterSetDatapathCapabilities(
    _In_ NETADAPTER Adapter
)
{
    // Get the device context
    PMY_DEVICE_CONTEXT deviceContext = GetMyContextFromDevice(Adapter);

    // Set various capabilities such as link layer MTU size, link layer capabilities, and power capabilities
    ...   

    // Initialize the Tx DMA capabilities structure
    NET_ADAPTER_DMA_CAPABILITIES txDmaCapabilities;
    NET_ADAPTER_DMA_CAPABILITIES_INIT(&txDmaCapabilities,
                                      deviceContext->dmaEnabler);

    // Set Tx capabilities
    NET_ADAPTER_TX_CAPABILITIES txCapabilities;
    NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA(&txCapabilities,
                                             &txDmaCapabilities,
                                             1);
    txCapabilities.FragmentRingNumberOfElementsHint = deviceContext->NumTransmitControlBlocks * MAX_PHYS_BUF_COUNT;
    txCapabilities.MaximumNumberOfFragments = MAX_PHYS_BUF_COUNT;

    // Initialize the Rx DMA capabilities structure
    NET_ADAPTER_DMA_CAPABILITIES rxDmaCapabilities;
    NET_ADAPTER_DMA_CAPABILITIES_INIT(&rxDmaCapabilities,
                                      deviceContext->dmaEnabler);

    // Set Rx capabilities
    NET_ADAPTER_RX_CAPABILITIES rxCapabilities;
    NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA(&rxCapabilities,
                                                        &rxDmaCapabilities,
                                                        MAX_PACKET_SIZE + FRAME_CRC_SIZE + RSVD_BUF_SIZE,
                                                        1);
    rxCapabilities.FragmentBufferAlignment = 64;
    rxCapabilities.FragmentRingNumberOfElementsHint = deviceContext->NumReceiveBuffers;

    // Set the adapter's datapath capabilities
    NetAdapterSetDatapathCapabilities(Adapter, 
                                      &txCapabilities, 
                                      &rxCapabilities);
}