Partager via


Gestion des tampons de données réseau

La gestion des tampons est une fonctionnalité qui permet aux pilotes clients de la carte d’interface réseau (NIC) et au système d’exploitation de travailler ensemble lors de l’allocation des tampons de données de paquets à partir de la mémoire système pour les chemins de données de transmission (Tx) et de réception (Rx). Cela peut entraîner une performance plus rapide pour la NIC, une gestion plus facile de la durée de vie de la mémoire pour le pilote client de la NIC, et plus de contrôle pour le système sur la mémoire.

Les avantages de la gestion des tampons dans NetAdapterCx

Le choix de l’emplacement d’allocation des tampons de données à partir de la mémoire système pour les charges utiles de paquets est crucial pour la performance du chemin de données. Dans NetAdapterCx, le modèle de gestion des tampons est optimisé pour le matériel NIC capable de DMA, et la meilleure façon pour les pilotes clients de tirer parti de cela est de laisser le système allouer des tampons de données en leur nom pour les chemins Tx et Rx. Cependant, les pilotes clients peuvent toujours influencer l’endroit et la manière dont le système alloue les tampons de données afin qu’ils puissent être facilement consommés par le matériel du client.

Considérez une NIC typique capable de DMA, par exemple. Il y a plusieurs avantages à cette approche :

  1. Les tampons de données sont alloués et libérés par le système. Par conséquent, le pilote client est libéré du fardeau de la gestion de la durée de vie de la mémoire.
  2. Le système s’assure que les tampons de données alloués sont prêts pour le DMA pour le matériel de la NIC en fonction des capacités déclarées par le pilote client. Ensuite, le pilote client peut simplement programmer les tampons de données dans leur matériel tels quels sans effectuer d’opérations de mappage DMA supplémentaires.
  3. Le système peut prendre en compte les besoins des applications de couche supérieure lors de l’allocation des tampons de données, afin qu’il puisse décider d’optimiser pour les performances globales de bout en bout plutôt que seulement pour les performances locales de bout en bout.

Pour les NIC non capables de DMA comme une clé réseau USB, ou pour d’autres NIC avancées/logiciels, le modèle de gestion des tampons offre également une option pour laisser la gestion des tampons de données entièrement au pilote client.

Comment tirer parti de la gestion des tampons

Important

Si votre matériel est capable de DMA, vous devrez créer un objet WDFDMAENABLER avant de définir vos capacités Rx et Tx. Lorsque vous configurez votre objet WDFDMAENABLER avec la structure WDF_DMA_ENABLER_CONFIG, assurez-vous de définir le membre WdmDmaVersionOverride sur 3 pour spécifier la version DMA 3.

Pour opter pour la gestion des tampons, suivez ces étapes :

  1. Lors du démarrage de votre adaptateur réseau, mais avant d’appeler NetAdapterStart, informez le système des capacités et des contraintes de tampon de données de votre matériel en utilisant les structures de données NET_ADAPTER_RX_CAPABILITIES et NET_ADAPTER_TX_CAPABILITIES pour les chemins Rx et Tx respectivement.
  2. Initialisez les deux structures de capacités en appelant l’une des fonctions d’initialisation. Par exemple, un pilote client de NIC capable de DMA utiliserait NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA et NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA pour déclarer ses capacités DMA matérielles et pour demander au système de gérer complètement les tampons de données en son nom.
  3. Passez les structures de capacités Tx et Rx initialisées à la méthode NetAdapterSetDatapathCapabilities.

Exemple

L’exemple suivant illustre les étapes de base décrites dans la section précédente pour commencer à utiliser le gestionnaire de tampons dans votre pilote client NIC. L’exemple utilise le DMA pour Tx et Rx, il a donc déjà créé un objet WDFDMAENABLER qu’il a stocké dans son espace de contexte de périphérique.

Notez que l’exemple définit également des indices sur ses tampons de fragments après avoir initialisé les structures de capacités Tx et Rx. Ces indices peuvent être utilisés par NetAdapterCx et les pilotes de protocole pour améliorer les performances.

La gestion des erreurs a été omise pour plus de clarté.

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);
}