KMDF, DMA, and Scatter gather lists

Hi,

When I try to allocate a common buffer to setup the hardware SGLs
underneath my callback from
WdfDmaTransactionInitializeUsingRequest(…), I get an int 3 breakpoint
when my callback tries to execute WdfCommonBufferCreateWithConfig. I’m
using the same dma enabler object to construct the common buffer and to
setup the transfer. Other than preallocating the common buffers in a
pool, is there a way to eliminate the breakpoint?

Jeff

You mean you’re getting a breakpoint from KMDF Verifier, right?

Did you look at the in flight recorder data (!WDFLOGDUMP) to determine the cause of the break?? You might want to (a) dump the stack, (b) follow the break out to the point where you call the function that causes the breakpoint and THEN look at the log again (as described in this article: http://www.osronline.com/article.cfm?article=496)

Peter
OSR

xxxxx@osr.com wrote:

You mean you’re getting a breakpoint from KMDF Verifier, right?

Did you look at the in flight recorder data (!WDFLOGDUMP) to determine the cause of the break?? You might want to (a) dump the stack, (b) follow the break out to the point where you call the function that causes the breakpoint and THEN look at the log again (as described in this article: http://www.osronline.com/article.cfm?article=496)

Peter
OSR

Ah, Thanks for the black box dumper. Another web-page described how to
do it, but missed one of your steps.

It seems that I am attempting to allocate memory at the wrong IRQL. So
the best thing to do then is to preallocate a bunch of common buffer
pages, then?

Jeff

Well, not knowing what you’re doing, the answer would be (a) yes, (b) no, (c) maybe.

In general, when using continuous DMA, one allocates a single “common buffer” during driver initialization (or, less often, a couple of such buffers). Those buffers are then shared between the driver and the device, across all I/O transactions.

Does that sound like the design you’re using??

Peter
OSR

xxxxx@osr.com wrote:

Well, not knowing what you’re doing, the answer would be (a) yes, (b) no, (c) maybe.

In general, when using continuous DMA, one allocates a single “common buffer” during driver initialization (or, less often, a couple of such buffers). Those buffers are then shared between the driver and the device, across all I/O transactions.

Does that sound like the design you’re using??

Peter
OSR

My DMA engine is packet-based w/ scatter-gather. The DMA engine reads a
scatter gather linked list from memory. That’s why I need the common
buffer. I’d rather allocate the SGL memory on-demand, rather than
preallocate it during device-driver initialization. Thoughts?

(So I don’t get the IRQL violation when my pool preallocates a some SGL
nodes during device-driver init)

Jeff

So you have a packet-based arrangement, where you have one or more S/G lists that comprise work for the device.

It’s hard to say what’s best without knowing how your device works. The way this is typically done is you allocate the shared memory during driver initialization, and you continually use that shared memory to communicate with your device. Maybe there’s a ring-buffer that’s setup there, or whatever.

The point here is that by doing this you avoid doing a memory allocate operation (which can, of course, fail and even when it works it adds overhead) in the path of each and every I/O operation you perform. This allows you to simply get the packet, build the S/G list that describes the buffer, slap a pointer to that S/G list onto your device, and hit the go bit.

P

xxxxx@osr.com wrote:

So you have a packet-based arrangement, where you have one or more S/G lists that comprise work for the device.

It’s hard to say what’s best without knowing how your device works. The way this is typically done is you allocate the shared memory during driver initialization, and you continually use that shared memory to communicate with your device. Maybe there’s a ring-buffer that’s setup there, or whatever.

The point here is that by doing this you avoid doing a memory allocate operation (which can, of course, fail and even when it works it adds overhead) in the path of each and every I/O operation you perform. This allows you to simply get the packet, build the S/G list that describes the buffer, slap a pointer to that S/G list onto your device, and hit the go bit.

P

Sure, I’ve implemented a lookaside buffer for my SGL’s. My lookaside
buffer went to KMDF’s allocate common buffer when it’s free store was
empty. So you’re saying that I just need to make sure my free store
always has enough space in it. Ok. I’ll do that.

Thanks,

Jeff

> buffer. I’d rather allocate the SGL memory on-demand, rather than

preallocate it during device-driver initialization. Thoughts?

Common buffers for SGLs are usually preallocated at device start time, for
instance, SCSIPORT does this.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com