2017-06-28 4 views
0

Je travaille sur un pilote de filtre NDIS qui copie réellement les données de NET_BUFFERs dans les tampons alloués par le pilote dans le chemin d'envoi et les place dans une file d'attente interne. Plus tard, les données sont à nouveau copiées de ces tampons alloués par le pilote dans la file d'attente vers les tampons IRP. Je veux éviter cette copie de données.Comment éviter la copie de données dans le pilote de filtre NDIS

Sous Linux, nous pouvons créer un clone de skbuff et le skbuff cloné peut être mis en file d'attente pour une utilisation ultérieure. Y at-il une option similaire disponible dans Windows? S'il existe un moyen de cloner le NET_BUFFER, nous pouvons simplement éviter la première copie qui se passe de NET_BUFFER aux tampons de mémoire alloués au pilote.

S'il existe un moyen d'obtenir une copie nulle depuis les NetBufferLists vers les tampons IRP, alors ce serait vraiment une solution idéale. Il serait vraiment utile si quelqu'un peut proposer une meilleure solution pour éviter les copies dans le chemin d'envoi.

Répondre

2

Il n'est pas clair pour moi pourquoi vous avez besoin de copier le NB (NET_BUFFER) du tout. Si vous envisagez de mettre en file d'attente le NB pour le traitement sur un thread différent, vous pouvez le faire avec le NB original — pas besoin de copier quoi que ce soit. La seule raison pour laquelle vous auriez besoin de copier la charge utile est que si vous prévoyez de rester sur le tampon pendant un certain temps (par exemple, plus de 1000ms). À un niveau élevé, la charge utile associée à un NB appartient à l'application. NDIS vous permet de mettre en file d'attente le NB, d'effectuer un traitement, de le supprimer, de le modifier, etc. Mais (en fonction des options de socket) l'application peut être bloquée jusqu'à ce que son tampon soit complété. Vous ne pouvez donc pas conserver le NB original ou sa charge utile indéfiniment. Si vous faites quelque chose qui prend beaucoup de temps, vous devez allouer une copie complète de toutes les structures de données dont vous avez besoin (NBL, NB, MDL et le tampon de charge utile) et renvoyer les originaux à l'application.

Si vous bourrez la charge utile de paquet dans un IRP afin qu'un processus usermode puisse contempler la charge utile, alors vous avez vraiment besoin d'une copie. La raison en est que le noyau ne peut faire confiance à aucun processus usermode pour faire quoi que ce soit dans un budget temps particulier. Imaginez, par exemple, que le système va hiberner. Le noyau suspend dûment tous les processus usermode, puis attend que chaque périphérique passe à un état de faible consommation. Mais la carte réseau ne peut pas passer à faible puissance, car le chemin de données ne s'arrête pas car un paquet est bloqué dans votre pilote de filtre, attendant que le processus usermode (maintenant suspendu) réponde. Ainsi, vous vous protégez en détachant l'IO à l'usermode avec l'IO sur le périphérique réseau: faites une copie. Mais si tout ce que vous faites est d'expédier le paquet à un autre périphérique de noyau qui fait (par exemple) le cryptage, alors vous pouvez supposer que le dispositif de cryptage assure un budget raisonnable, donc il peut être sûr de donner l'original la charge utile du paquet.

+0

Merci pour la réponse! J'ai vraiment besoin de copier la charge utile dans NB et de la passer à un processus en mode utilisateur appelant read. À l'heure actuelle, dans SendNetBufferLists(), la charge utile dans NB est copiée dans un tampon intermédiaire alloué par le pilote et ce tampon intermédiaire est ajouté à une file d'attente. Dans la routine dispatch (read), le tampon intermédiaire est retiré de la file d'attente et copié dans le tampon IRP. Je veux copier la charge utile directement de NB vers le tampon IRP, ce qui devrait être possible si nous pouvons mettre NB dans une file d'attente. Cela permettrait d'économiser une copie. Ce serait vraiment utile si vous pouvez suggérer un moyen de le faire. –