NET_BUFFER_LISTS in miniport send operations...

Hi all,

Recall that I’m writing an ndis miniport to access a NIC in a
virtualization Windows guest.

I’ve studied the NET_BUFFER* online documentation and the
usbwifi/xframeii samples but am still confused as to what I am looking
at.

In particular, I’m starting with the SEND operation.

First off, does Windows provide any sort of linearization capability
such that a NET_BUFFER MDL would point to a complete packet? I see the
use of the scatter/gather operations in the samples, so I’m not sure
this even exists.

Does an (NET_BUFFER) MDL point to non-paged memory? Or will I need to
pin it with MmProbeAndLockPages()? (I haven’t seen this in the samples,
but I’m not sure.)

If I NdisMRegisterScatterGatherDma with a MaximumPhysicalMapping of the
ethernet packet size, does the SGList I obtain point to complete
packets?

I’m struggling with how to conceptually understand how to get to packets
from a NET_BUFFER_LIST for sending. The samples are helpful however
I’m still sorting out the differences between them.

Thanks for any and all help.

-PWM

Are you setting up DMA or do you otherwise need access to the physical pages
to perform whatever constitutes a ‘transfer’ in your case?

Just what would you like to do with the frame ‘data’, or the SG List, or
both?

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter W. Morreale
Sent: Thursday, December 31, 2009 10:44 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NET_BUFFER_LISTS in miniport send operations…

Hi all,

Recall that I’m writing an ndis miniport to access a NIC in a
virtualization Windows guest.

I’ve studied the NET_BUFFER* online documentation and the
usbwifi/xframeii samples but am still confused as to what I am looking
at.

In particular, I’m starting with the SEND operation.

First off, does Windows provide any sort of linearization capability
such that a NET_BUFFER MDL would point to a complete packet? I see the
use of the scatter/gather operations in the samples, so I’m not sure
this even exists.

Does an (NET_BUFFER) MDL point to non-paged memory? Or will I need to
pin it with MmProbeAndLockPages()? (I haven’t seen this in the samples,
but I’m not sure.)

If I NdisMRegisterScatterGatherDma with a MaximumPhysicalMapping of the
ethernet packet size, does the SGList I obtain point to complete
packets?

I’m struggling with how to conceptually understand how to get to packets
from a NET_BUFFER_LIST for sending. The samples are helpful however
I’m still sorting out the differences between them.

Thanks for any and all help.

-PWM


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> Does an (NET_BUFFER) MDL point to non-paged memory? Or will I need to

pin it with MmProbeAndLockPages()? (I haven’t seen this in the samples,
but I’m not sure.)

No.

The Windows convention is that MmProbeAndLockPages must be called immediately after IoAllocateMdl in the same module. The unlocked MDLs are never passed across modules.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

On Thu, 2009-12-31 at 11:53 -0500, David R. Cattley wrote:

Are you setting up DMA or do you otherwise need access to the physical pages
to perform whatever constitutes a ‘transfer’ in your case?

Well… This is where I am confused. No, I do not need to setup DMA,
since I’m a virtualized guest, I merely need to know that the packets
are pinned in memory, and what the physical address/length is for
enabling the ‘transfer’.

I was only looking at ScatterGatherDMA functions because the samples I
have make use of them. Just trying to understand what is available.

Just what would you like to do with the frame ‘data’, or the SG List, or
both?

Ideally? A pointer/len to each pinned frame data. That is all I need.

I can work with a SG list, however since I’m new to network drivers, I’d
*love* to keep this as simple as possible for the moment.

I’m just very confused about what I’m looking at wrt a NBL.

THanks,
-PWM

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter W. Morreale
Sent: Thursday, December 31, 2009 10:44 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NET_BUFFER_LISTS in miniport send operations…

Hi all,

Recall that I’m writing an ndis miniport to access a NIC in a
virtualization Windows guest.

I’ve studied the NET_BUFFER* online documentation and the
usbwifi/xframeii samples but am still confused as to what I am looking
at.

In particular, I’m starting with the SEND operation.

First off, does Windows provide any sort of linearization capability
such that a NET_BUFFER MDL would point to a complete packet? I see the
use of the scatter/gather operations in the samples, so I’m not sure
this even exists.

Does an (NET_BUFFER) MDL point to non-paged memory? Or will I need to
pin it with MmProbeAndLockPages()? (I haven’t seen this in the samples,
but I’m not sure.)

If I NdisMRegisterScatterGatherDma with a MaximumPhysicalMapping of the
ethernet packet size, does the SGList I obtain point to complete
packets?

I’m struggling with how to conceptually understand how to get to packets
from a NET_BUFFER_LIST for sending. The samples are helpful however
I’m still sorting out the differences between them.

Thanks for any and all help.

-PWM


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

That information is in the chain of MDLs attached to each NET_BUFFER in a
NET_BUFFER_LIST.

Let me preface the next bit by saying I am just trying to ‘explain’ how a
frame might look going from NET_BUFFER to physical pages. I am not
suggesting that the best solution for your situation is to use this
explanation as a coding guide.

NET_BUFFERs own a chain of MDLs.

Each MDL is a virtually contiguous but possibly physically discontiguous
memory chunk.

The MDL describes the chunk by giving you an offset into the first page at
which the chunk starts, the number of pages, the total length of the chunk
from which you can derive the ending offset of the chunk in the last page,
and a list of pages (aka, the PFNs).

I hope it is clear at this point that even if a network frame - a single
NET_BUFFER, with a MDL chain consisting of a single MDL, could straddle two
(or more but not for normal Ethernet) pages which are physically
non-contiguous.

Now a single network frame is much more likely, especially in the send path,
to comprised of multiple MDLs linked together in a chain. The MDL chain now
describes a “logically contiguous” but “virtual discontiguous” frame. Each
chunk is itself possibly backed by physically discontiguous pages.

You could, of course, head down the path of traversing the MdlChain,
building the PAGE/Offset/Length array, etc. but all of this is opaquely
managed for you by NDIS if you use the NDIS DMA abstraction.

By registering (as you have done) with NdisMRegisterScatterGatherDma() you
are using the NDIS mechanism. I suggest you specify NULL for the
ScatterGatherListBuffer and zero for the ScatterGatherListBufferSize and let
NDIS sort that out for you initially. Optimize later. These are a buffer
for the SGList, not a buffer for the frame.

When you then call NdisMAllocateNetBufferSGList(), NDIS does the heavy
lifting, walks the MDL Chain, builds the SG list, and then calls your
MiniportProcessSGList() callback function with the SG list built up for you.
You get a pointer to a SCATTER_GATHER_LIST which is a variable sized array
of SCATTER_GETHER_ELEMENTs (roughly) and those are simply
[PhysicalAddress:Length] pairs.

At that point, you have all of the pages, page offsets, and lengths.

When you are done with the transfer operation (virtual as it might be), you
free the SG list with NdisMFreeNetBufferSGList() and then complete the send
operation for that NET_BUFFER. When all of the NET_BUFFERs in a
NET_BUFFER_LIST have been sent, you can return (complete) the
NET_BUFFER_LIST.

Admittedly it does not sound simple but then again, this is DMA. If your
virtual network bridge is expecting something other than a list of
PAGE/Offset/Length representing a single ‘frame’ then you are probably
screwed and will have to copy the frame to bounce buffer that you allocate
with the properties necessary.

Remember http://www.osronline.com/showThread.cfm?link=169395 ?

Mr. Oshins posted in that thread tersely but in essence saying, “hey, if you
have the MDLs, you have what you need” (my paraphrasing). Well, in NDIS,
even building the SGList is something you can delegate the heavy lifting to
the Port Driver (NDIS) and simply provide some callbacks.

I hope this helps.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter W. Morreale
Sent: Thursday, December 31, 2009 12:32 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] NET_BUFFER_LISTS in miniport send operations…

On Thu, 2009-12-31 at 11:53 -0500, David R. Cattley wrote:

Are you setting up DMA or do you otherwise need access to the physical
pages
to perform whatever constitutes a ‘transfer’ in your case?

Well… This is where I am confused. No, I do not need to setup DMA,
since I’m a virtualized guest, I merely need to know that the packets
are pinned in memory, and what the physical address/length is for
enabling the ‘transfer’.

I was only looking at ScatterGatherDMA functions because the samples I
have make use of them. Just trying to understand what is available.

Just what would you like to do with the frame ‘data’, or the SG List, or
both?

Ideally? A pointer/len to each pinned frame data. That is all I need.

I can work with a SG list, however since I’m new to network drivers, I’d
*love* to keep this as simple as possible for the moment.

I’m just very confused about what I’m looking at wrt a NBL.

THanks,
-PWM

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter W. Morreale
Sent: Thursday, December 31, 2009 10:44 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NET_BUFFER_LISTS in miniport send operations…

Hi all,

Recall that I’m writing an ndis miniport to access a NIC in a
virtualization Windows guest.

I’ve studied the NET_BUFFER* online documentation and the
usbwifi/xframeii samples but am still confused as to what I am looking
at.

In particular, I’m starting with the SEND operation.

First off, does Windows provide any sort of linearization capability
such that a NET_BUFFER MDL would point to a complete packet? I see the
use of the scatter/gather operations in the samples, so I’m not sure
this even exists.

Does an (NET_BUFFER) MDL point to non-paged memory? Or will I need to
pin it with MmProbeAndLockPages()? (I haven’t seen this in the samples,
but I’m not sure.)

If I NdisMRegisterScatterGatherDma with a MaximumPhysicalMapping of the
ethernet packet size, does the SGList I obtain point to complete
packets?

I’m struggling with how to conceptually understand how to get to packets
from a NET_BUFFER_LIST for sending. The samples are helpful however
I’m still sorting out the differences between them.

Thanks for any and all help.

-PWM


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

On Thu, 2009-12-31 at 14:22 -0500, David R. Cattley wrote:

I hope it is clear at this point that even if a network frame - a single
NET_BUFFER, with a MDL chain consisting of a single MDL, could straddle two
(or more but not for normal Ethernet) pages which are physically
non-contiguous.

The key point I had assumed, but was not sure. That a NET_BUFFER
represents a frame for a miniport. Perfect.

When you then call NdisMAllocateNetBufferSGList()

Nod, this is exactly what I was thinking from seeing and parsing the
examples. Very glad to find out all that time spent was worth it. I do
understand the model presented.

And yes, the bridge only requires a addr/offset/len for the ‘transfer’.
It also supports SG itself.

This has become very clear to me now. Thank you so much for clearing
this up.

Best,
-PWM