Función NdisMAllocateSharedMemory (ndis.h)
Precaución
En el caso de los procesadores ARM y ARM64, se recomienda encarecidamente que los escritores de controladores NDIS usen WDF DMA o WDM DMA en lugar de NDIS Scatter/Gather DMA.
Para obtener más información sobre WDF DMA, vea Control de operaciones de DMA en controladores kmDF.
Para obtener más información sobre WDM DMA, consulte los temas secundarios relacionados con DMA de Administración de entrada y salida para controladores.
NdisMAllocateSharedMemory asigna y asigna un intervalo de memoria de host para que el intervalo de memoria sea accesible simultáneamente desde el sistema host y una NIC DMA.
Sintaxis
void NdisMAllocateSharedMemory(
[in] NDIS_HANDLE MiniportAdapterHandle,
[in] ULONG Length,
[in] BOOLEAN Cached,
[out] PVOID *VirtualAddress,
[out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);
Parámetros
[in] MiniportAdapterHandle
Especifica la entrada de identificador en MiniportInitializeEx.
[in] Length
Especifica el número de bytes para asignar.
[in] Cached
Este parámetro se omite (la memoria almacenada en caché siempre se usa en sistemas x86 y x64).
[out] VirtualAddress
Puntero a una variable proporcionada por el autor de la llamada en la que esta función devuelve la dirección virtual base de la asignación para su uso por parte del controlador de miniport. Si NdisMAllocateSharedMemory no puede satisfacer su llamador, devuelve NULL para indicar que no se asignó ninguna memoria.
[out] PhysicalAddress
Puntero a una variable proporcionada por el autor de la llamada en la que esta función devuelve una dirección física, adecuada para su uso por la NIC, que corresponde a la que se devuelve en VirtualAddress o devuelve NULL.
Valor devuelto
None
Observaciones
NdisMAllocateSharedMemory proporciona el intervalo de direcciones virtuales asignado que usa el controlador para acceder al bloque de memoria compartida y al intervalo de NDIS_PHYSICAL_ADDRESS tipo que usa la NIC. El sistema puede asignar doblemente un valor devuelto en PhysicalAddress . Es decir, un intervalo de direcciones "físico" descrito por el valor de PhysicalAddress y Length puede ser un intervalo de direcciones lógicas asignadas que no coinciden con las direcciones físicas del host para la asignación en todas las plataformas posibles.
Solo se puede llamar a NdisMAllocateSharedMemory desde MiniportInitializeEx. El tamaño de una asignación a la solicitud depende de cómo el escritor de controladores, conocer las funcionalidades y características de la NIC, decide hacer que el equilibrio entre el rendimiento y el siguiente dilema de tamaño:
-
En períodos de tráfico de red elevado, un controlador de minipuerto no puede mantener un alto rendimiento de E/S si se ejecuta bajo en el espacio de memoria compartido para los búferes de datos accesibles para dispositivos.
Por ejemplo, el controlador de minipuerto podría indicar que los búferes de recepción en memoria compartida son más rápidos que dichos búferes se devuelven de controladores de protocolo enlazados cuando una inundación de recepción entra en una NIC. Si todos sus espacios de memoria compartidos se consumen en búferes de recepción pendientes, es posible que el controlador de miniporte tenga que deshabilitar las interrupciones de recepción en una NIC hasta que tenga algún espacio de memoria compartido disponible para los búferes de recepción.
- Por otro lado, llamar a NdisMAllocateSharedMemory con una longitud elegida para anticipar cierta demanda máxima de transferencia hace que la imagen del controlador sea más grande y su uso de recursos sea bastante poco económico, excepto durante períodos excepcionales de demanda de E/S muy altas. Además, NdisMAllocateSharedMemory podría no proporcionar al controlador un bloque tan grande si no hay suficiente memoria del sistema disponible, lo que obliga al controlador a producir un error en la inicialización.
NdisMAllocateSharedMemory y NdisMAllocateSharedMemoryAsyncEx son las únicas funciones de NdisXxx a las que se puede llamar para asignar memoria de host compartida entre el controlador, que usa direcciones virtuales y una NIC, que usa las direcciones lógicas correspondientes.
Un controlador de minipuerto debe alinear los búferes que asigna de la memoria almacenada en caché compartida en una parte integral del límite de la línea de caché de datos del host para evitar el desgarro de la línea de caché durante DMA. El desgarro de la línea de caché puede provocar problemas de integridad de datos en el controlador o degradar el rendimiento de E/S del controlador (y del sistema) al requerir un vaciado excesivo de caché de datos para mantener la integridad de los datos. MiniportInitializeEx puede llamar a NdisMGetDmaAlignment para determinar el límite de alineación en la plataforma actual para los búferes accesibles para dispositivos que el controlador configurará dentro de un intervalo asignado de memoria compartida.
Un controlador de minipuerto debe establecer un límite en la cantidad de memoria compartida que puede asignar. Este límite es específico del controlador y debe ser lo suficientemente alto como para que el controlador no se quede sin búferes. No establezca un límite excesivamente alto, ya que esto podría dar lugar a un consumo desperdiciado de memoria compartida que podría reducir el rendimiento del sistema.
MiniportInitializeEx también puede llamar a NdisSystemProcessorCount antes de llamar a NdisMAllocateSharedMemory si el escritor de controladores decide asignar un bloque de memoria compartido mayor en máquinas multiprocesador en la suposición de que es probable que cualquier máquina SMP sea un servidor de red con mayores demandas de transferencia de red en la NIC que en una estación de trabajo.
Si se produce un error en su llamada a NdisMAllocateSharedMemory , MiniportInitializeEx puede llamar de nuevo a la solicitud de una asignación más pequeña. Sin embargo, si MiniportInitializeEx no puede asignar suficiente memoria compartida para la NIC, debe liberar todos los recursos que ya ha asignado y conmutar por error la inicialización.
Si el controlador de minipuerto indica posteriormente que recibe con NdisMIndicateReceiveNetBufferLists, debe asignar cierto número de descriptores de búfer del grupo de búferes que asignan los búferes de recepción de la NIC en el bloque de memoria compartida.
Si la memoria asignada se almacena en caché y, por lo tanto, debe vaciarse en las transferencias, el controlador de miniporte debe llamar a NdisAllocateMdl para asignar un descriptor de tipo NDIS_BUFFER para el intervalo de memoria compartida. El controlador de minipuerto debe llamar a KeFlushIoBuffers con este descriptor de búfer para realizar este vaciado.
Si un controlador de minipuerto llama a NdisMAllocateSharedMemoryAsyncEx o NdisMAllocateSharedMemory, debe liberar todas las asignaciones pendientes con una o varias llamadas a NdisMFreeSharedMemory cuando se quita una NIC, es decir, cuando se llama a su función MiniportHaltEx .
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Compatible con NDIS 6.0 y versiones posteriores. |
Plataforma de destino | Universal |
Encabezado | ndis.h (incluya Ndis.h) |
Library | Ndis.lib |
IRQL | PASSIVE_LEVEL |