NdisMAllocateSharedMemory, fonction (ndis.h)
Prudence
Pour les processeurs ARM et ARM64, nous recommandons vivement aux enregistreurs de pilotes NDIS d’utiliser WDF DMA ou WDM DMA au lieu de NDIS Scatter/Collect DMA.
Pour plus d’informations sur WDF DMA, consultez gestion des opérations DMA dans les pilotes KMDF.
Pour plus d’informations sur WDM DMA, consultez les rubriques enfants relatives à DMA de Gestion des entrées/sorties pour les pilotes.
NdisMAllocateSharedMemory alloue et mappe une plage de mémoire hôte afin que la plage de mémoire soit simultanément accessible à partir du système hôte et d’une carte réseau DMA.
Syntaxe
void NdisMAllocateSharedMemory(
[in] NDIS_HANDLE MiniportAdapterHandle,
[in] ULONG Length,
[in] BOOLEAN Cached,
[out] PVOID *VirtualAddress,
[out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);
Paramètres
[in] MiniportAdapterHandle
Spécifie l’entrée de handle pour MiniportInitializeEx.
[in] Length
Spécifie le nombre d’octets à allouer.
[in] Cached
Ce paramètre est ignoré (la mémoire mise en cache est toujours utilisée sur les systèmes x86 et x64).
[out] VirtualAddress
Pointeur vers une variable fournie par l’appelant dans laquelle cette fonction retourne l’adresse virtuelle de base de l’allocation à utiliser par le pilote miniport. Si NdisMAllocateSharedMemory ne peut pas satisfaire son appelant, il retourne NULL pour indiquer qu’aucune mémoire n’a été allouée.
[out] PhysicalAddress
Pointeur vers une variable fournie par l’appelant dans laquelle cette fonction retourne une adresse physique, adaptée à l’utilisation par la carte réseau, qui correspond à celle retournée à VirtualAddress, ou retourne NULL.
Valeur de retour
Aucun
Remarques
NdisMAllocateSharedMemory fournit à la fois la plage d’adresses virtuelle mappée utilisée par le pilote pour accéder au bloc de mémoire partagée et à la plage NDIS_PHYSICAL_ADDRESS-type utilisée par la carte réseau. Une valeur retournée à physicalAddress peut être doublement mappée par le système. Autrement dit, une plage d’adresses « physique » décrite par la valeur de PhysicalAddress et Length peut être une plage d’adresses logiques mappées qui ne correspondent pas aux adresses physiques de l’hôte pour l’allocation dans chaque plateforme possible.
NdisMAllocateSharedMemory ne peut être appelé qu’à partir de MiniportInitializeEx. La taille d’une allocation à demander dépend de la façon dont l’enregistreur de pilotes, sachant les fonctionnalités et les fonctionnalités de la carte réseau, décide de faire le compromis entre les performances suivantes et le dilemme de taille :
-
Dans les périodes de trafic réseau élevé, un pilote miniport ne peut pas conserver un débit d’E/S élevé s’il s’exécute faiblement sur l’espace mémoire partagé pour les mémoires tampons de données accessibles par l’appareil.
Par exemple, le pilote miniport peut indiquer que les mémoires tampons de réception en mémoire partagée sont plus rapides que ces mémoires tampons sont retournées par des pilotes de protocole liés lorsqu’une inondation de réceptions arrive à une carte réseau. Si tous ses espaces de mémoire partagée sont consommés par des mémoires tampons de réception en attente, le pilote miniport peut devoir désactiver les interruptions de réception sur une carte réseau jusqu’à ce qu’il dispose d’un espace mémoire partagé disponible pour les mémoires tampons de réception.
- En revanche, l’appel de NdisMAllocateSharedMemory avec une Longueur choisie pour anticiper une demande de transfert maximale rend l’image du pilote plus grande et son utilisation des ressources assez peu économique, à l’exception des rares périodes de demande d’E/S très élevées. De plus, NdisMAllocateSharedMemory risque de ne pas donner au pilote un bloc si la mémoire système insuffisante est disponible, forçant le pilote à échouer l’initialisation.
NdisMAllocateSharedMemory et NdisMAllocateSharedMemoryAsyncEx sont les seules fonctions NdisXxx qui peuvent être appelées pour allouer la mémoire hôte partagée entre le pilote, qui utilise des adresses virtuelles et une carte réseau, qui utilise les adresses logiques correspondantes.
Un pilote miniport doit aligner les mémoires tampons qu’il alloue à partir de la mémoire mise en cache partagée sur une partie intégrante de la limite de ligne de cache de données hôte pour empêcher la déchirure de ligne de cache pendant DMA. La déchirure de ligne de cache peut entraîner des problèmes d’intégrité des données dans le pilote ou dégrader les performances d’E/S du pilote (et du système) en nécessitant un vidage excessif du cache de données pour maintenir l’intégrité des données. MiniportInitializeEx pouvez appeler NdisMGetDmaAlignment pour déterminer la limite d’alignement dans la plateforme actuelle pour les mémoires tampons accessibles aux appareils que le pilote configurera dans une plage allouée de mémoire partagée.
Un pilote miniport doit définir une limite sur la quantité de mémoire partagée qu’il peut allouer. Cette limite est spécifique au pilote et doit être suffisamment élevée pour que le pilote ne manque pas de mémoires tampons. Ne définissez pas de limite excessivement élevée, car cela peut entraîner une consommation gaspilleuse de la mémoire partagée qui peut réduire les performances du système.
MiniportInitializeEx peut également appeler NdisSystemProcessorCount avant d’appeler NdisMAllocateSharedMemory si l’enregistreur de pilotes décide d’allouer un bloc de mémoire partagée plus volumineux dans les machines multiprocesseurs en supposant que n’importe quel ordinateur SMP est susceptible d’être un serveur réseau avec des demandes de transfert réseau plus élevées sur la carte réseau qu’une station de travail.
Si son appel à NdisMAllocateSharedMemory échoue, MiniportInitializeEx peut appeler à nouveau en demandant une allocation plus petite. Toutefois, si MiniportInitializeEx ne peut pas allouer suffisamment de mémoire partagée pour la carte réseau, elle doit libérer toutes les ressources qu’elle a déjà allouées et échouer l’initialisation.
Si le pilote miniport indique par la suite les réceptions avec NdisMIndicateReceiveNetBufferLists, il doit allouer un certain nombre de descripteurs de mémoire tampon du pool de mémoires tampons qui mappent les tampons de réception de la carte réseau dans le bloc de mémoire partagée.
Si la mémoire allouée est mise en cache et doit donc être vidée sur les transferts, le pilote miniport doit appeler NdisAllocateMdl pour allouer un descripteur de type NDIS_BUFFER pour la plage de mémoire partagée. Le pilote miniport doit appeler KeFlushIoBuffers avec ce descripteur de mémoire tampon pour effectuer une telle vidage.
Si un pilote miniport appelle NdisMAllocateSharedMemoryAsyncEx ou NdisMAllocateSharedMemory, il doit libérer toutes les allocations en attente avec un ou plusieurs appels à NdisMFreeSharedMemory lorsqu’une carte réseau est supprimée, autrement dit, quand sa fonction MiniportHaltEx est appelée.
Exigences
Exigence | Valeur |
---|---|
client minimum pris en charge | Prise en charge dans NDIS 6.0 et versions ultérieures. |
plateforme cible | Universel |
d’en-tête | ndis.h (include Ndis.h) |
bibliothèque | Ndis.lib |
IRQL | PASSIVE_LEVEL |