Compartir a través de


Administración del búfer de datos de red

La administración del búfer es una característica que permite que los controladores de cliente de tarjeta de interfaz de red (NIC) y el sistema operativo funcionen juntos al asignar búferes de datos de paquetes desde la memoria del sistema para las rutas de acceso de datos de transmisión (Tx) y recepción (Rx). Esto puede dar lugar a un rendimiento más rápido para la NIC, una administración más sencilla de la duración de la memoria para el controlador cliente de la NIC y un mayor control para el sistema sobre la memoria.

Las ventajas de la administración de búferes en NetAdapterCx

La elección de dónde se asignan los búferes de datos desde la memoria del sistema para las cargas de paquetes es fundamental para el rendimiento de la ruta de acceso de datos. En NetAdapterCx, el modelo de administración del búfer está optimizado para hardware NIC compatible con DMA y la mejor manera de que los controladores cliente aprovechen su ventaja es permitir que el sistema asigne búferes de datos en su nombre para las rutas de acceso Tx y Rx. Sin embargo, los controladores de cliente todavía pueden influir en dónde y cómo asigna el sistema los búferes de datos para que el hardware del cliente pueda consumirlos fácilmente.

Considere una NIC típica compatible con DMA, por ejemplo. Este enfoque tiene varias ventajas:

  1. El sistema asigna y libera los búferes de datos. Por lo tanto, el controlador cliente se libera de la carga de la administración de la duración de la memoria.
  2. El sistema garantiza que los búferes de datos asignados estén listos para DMA para el hardware NIC en función de las funcionalidades declaradas por el controlador cliente. A continuación, el controlador cliente simplemente puede programar los búferes de datos en su hardware tal como está sin realizar ninguna operación de asignación de DMA adicional.
  3. El sistema puede tener en cuenta las necesidades de las aplicaciones de nivel superior al asignar los búferes de datos, por lo que puede decidir optimizar el rendimiento global de un extremo a otro en lugar de solo el rendimiento de un extremo a otro local.

En el caso de las NIC que no son compatibles con DMA, como un dongle de red basado en USB, o para otras NIC avanzadas o de software, el modelo de administración del búfer de búfer también proporciona una opción para dejar completamente la administración del búfer de datos en el controlador cliente.

Cómo aprovechar la administración del búfer

Importante

Si el hardware es compatible con DMA, deberá crear un objeto WDFDMAENABLER antes de establecer las funcionalidades Rx y Tx. Al configurar el objeto WDFDMAENABLER con la estructura WDF_DMA_ENABLER_CONFIG, asegúrese de establecer el miembro miembro WdmDmaVersionOverride en 3 para especificar la versión 3 de DMA.

Para participar en la administración del búfer, siga estos pasos:

  1. Al iniciar el adaptador net, pero antes de llamar a NetAdapterStart, indique al sistema las funcionalidades y restricciones del búfer de datos del hardware mediante la estructura de datos NET_ADAPTER_RX_CAPABILITIES y NET_ADAPTER_TX_CAPABILITIES para la ruta de acceso Rx y Tx, respectivamente
  2. Inicialice las dos estructuras de funcionalidad llamando a una de las funciones de inicialización. Por ejemplo, un controlador de cliente NIC compatible con DMA usaría NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA y NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA para declarar sus niveles de DMA de hardware y para indicar al sistema que administre completamente los búferes de datos en su nombre.
  3. Pase las estructuras de funcionalidad Tx y Rx inicializadas al método NetAdapterSetDatapathCapabilities.

Ejemplo

En el ejemplo siguiente se muestran los pasos básicos descritos en la sección anterior para empezar a usar el administrador de búferes en el controlador de cliente NIC. En el ejemplo se usa DMA para Tx y Rx, por lo que creó previamente un objeto WDFDMAENABLER que almacenó en su espacio de contexto del dispositivo.

Tenga en cuenta que el ejemplo también establece algunas sugerencias sobre sus búferes de fragmentos después de inicializar las estructuras de funcionalidades Tx y Rx. NetAdapterCx y controladores de protocolo pueden usar estas sugerencias para mejorar el rendimiento.

Se ha omitido el control de errores por razones de claridad.

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