Hi,
how to share a very large buffer (i.e. about 500 MB, megabytes !!) between
user Memory and Kernel Memory ?

I allocate a buffer in user mode (with c++ new operator) and I pass the
pointer to my driver with an IOCTL.
Then I want to fill this memory with some data.
Data come from a DMA transfer, so I fill user buffer when I receive DMA done
interrupt.

If I use user pointer I get a system crash after some KB.
If I use MDL I cannot use use buffer larger about than 50MB (if size is too
large i get exception).

Some other ideas to make many DMA data pieces available to user as a large
buffer ?

Tahnk a lot,
Blu

Re: Sharing very large buffer between User and Kernel by Brian

Brian
Fri Feb 06 15:20:20 CST 2004

"blu" <b.lu@fastwebnet.it> wrote in message
news:%23L7UShM7DHA.2480@TK2MSFTNGP12.phx.gbl...
> Hi,
> how to share a very large buffer (i.e. about 500 MB, megabytes !!) between
> user Memory and Kernel Memory ?

Does it really need to be shared? Or, does it just need to be written by a DMA
engine on a controller?

> I allocate a buffer in user mode (with c++ new operator) and I pass the
> pointer to my driver with an IOCTL.
> Then I want to fill this memory with some data.
> Data come from a DMA transfer, so I fill user buffer when I receive DMA done
> interrupt.
>
> If I use user pointer I get a system crash after some KB.

Sure, the buffer may be virtually contiguous, but it is certainly not physically
contiguous.

> If I use MDL I cannot use use buffer larger about than 50MB (if size is too
> large i get exception).

Actually, I believe an MDL can map 64MB. Of course, you can chain a series of
MDLs together, but you will have to do that yourself.

>
> Some other ideas to make many DMA data pieces available to user as a large
> buffer ?

Side stepping for a moment the advisability of locking down 500MB of memory for
a DMA transfer, what you need to do is implement what is called 'Neither I/O',
which means the I/O manager will not do any pre-processing or post-processing of
the I/O requests for you - you have to do it all. The simplest way to implement
'Neither I/O' is to use a Device I/O Control (you could also just use ReadFile,
but don't set either DO_DIRECT_IO or DO_BUFFERED_IO in your device object flags;
of course, all your READs and WRITEs to the device will then be 'Neither I/O',
which is why I recommend using a Device I/O Control), and then in the dispatch
routine lock down the pages and build your MDL chain. Once that's done, the IRP
should then be passed to IoStartPacket. When the IRP reaches your Start I/O
routine, then build your scatter gather list and program your DMA engine. When
you complete the IRP in your DPC routine, the I/O manager will automatically
unlock and deallocate the MDL chain.

Are you sure that you REALLY need to lock down 500MB for a *single* DMA
transfer? If you don't have upwards of a gigabyte of physical memory this will
be very inconvenient. Is it a hardware requirement that you do 500MB transfers?
Unless it is very special hardware, it seems like a very poor design. Try and
break the transfer up into a series of smaller transfers.

-Brian

Brian Catlin, Sannas Consulting 310-944-9492
Windows Network, Video, WDM Device Driver Training & Consulting
See WWW.AZIUS.COM.bad for courses and scheduling
REMOVE .BAD FROM EMAIL AND WEB ADDRESS



Re: Sharing very large buffer between User and Kernel by Blu

Blu
Fri Feb 06 16:50:55 CST 2004

Hi,
thank for your answer.
Probably I didn't explain exactely what it is happening in my system :

My hardware executes many DMA transfer. After every transfer I get an
interrupt and I read some KB (maximum 64KB) of trasferred data.

What I have to do it is to join all DMA transfer in one big user buffer and
signal an event to user application when buffer is full. This way user will
see one big buffer (this is required by project specifications I'm working)
and will process it.

Looking in MSDN (Q191840 and Q194945) I found "section objects": the idea is
to create a section in user mode with CreateFileMapping and use
ZwOpenSection to open it in kernel mode. The only thing I cannot understand
from documentation it is if this way I use memory or Paging file. What do
you think about ?

Thank a lot,
Blu

"Brian Catlin" <brianc@sannas.org.bad> ha scritto nel messaggio
news:%23I4DIcP7DHA.2676@TK2MSFTNGP10.phx.gbl...
> "blu" <b.lu@fastwebnet.it> wrote in message
> news:%23L7UShM7DHA.2480@TK2MSFTNGP12.phx.gbl...
> > Hi,
> > how to share a very large buffer (i.e. about 500 MB, megabytes !!)
between
> > user Memory and Kernel Memory ?
>
> Does it really need to be shared? Or, does it just need to be written by
a DMA
> engine on a controller?
>
> > I allocate a buffer in user mode (with c++ new operator) and I pass the
> > pointer to my driver with an IOCTL.
> > Then I want to fill this memory with some data.
> > Data come from a DMA transfer, so I fill user buffer when I receive DMA
done
> > interrupt.
> >
> > If I use user pointer I get a system crash after some KB.
>
> Sure, the buffer may be virtually contiguous, but it is certainly not
physically
> contiguous.
>
> > If I use MDL I cannot use use buffer larger about than 50MB (if size is
too
> > large i get exception).
>
> Actually, I believe an MDL can map 64MB. Of course, you can chain a
series of
> MDLs together, but you will have to do that yourself.
>
> >
> > Some other ideas to make many DMA data pieces available to user as a
large
> > buffer ?
>
> Side stepping for a moment the advisability of locking down 500MB of
memory for
> a DMA transfer, what you need to do is implement what is called 'Neither
I/O',
> which means the I/O manager will not do any pre-processing or
post-processing of
> the I/O requests for you - you have to do it all. The simplest way to
implement
> 'Neither I/O' is to use a Device I/O Control (you could also just use
ReadFile,
> but don't set either DO_DIRECT_IO or DO_BUFFERED_IO in your device object
flags;
> of course, all your READs and WRITEs to the device will then be 'Neither
I/O',
> which is why I recommend using a Device I/O Control), and then in the
dispatch
> routine lock down the pages and build your MDL chain. Once that's done,
the IRP
> should then be passed to IoStartPacket. When the IRP reaches your Start
I/O
> routine, then build your scatter gather list and program your DMA engine.
When
> you complete the IRP in your DPC routine, the I/O manager will
automatically
> unlock and deallocate the MDL chain.
>
> Are you sure that you REALLY need to lock down 500MB for a *single* DMA
> transfer? If you don't have upwards of a gigabyte of physical memory this
will
> be very inconvenient. Is it a hardware requirement that you do 500MB
transfers?
> Unless it is very special hardware, it seems like a very poor design. Try
and
> break the transfer up into a series of smaller transfers.
>
> -Brian
>
> Brian Catlin, Sannas Consulting 310-944-9492
> Windows Network, Video, WDM Device Driver Training & Consulting
> See WWW.AZIUS.COM.bad for courses and scheduling
> REMOVE .BAD FROM EMAIL AND WEB ADDRESS
>
>



Re: Sharing very large buffer between User and Kernel by Brian

Brian
Fri Feb 06 19:28:09 CST 2004

"Blu" <b.lu@fastwebnet.it> wrote in message
news:el9VNPQ7DHA.632@TK2MSFTNGP12.phx.gbl...
> Hi,
> thank for your answer.
> Probably I didn't explain exactely what it is happening in my system :
>
> My hardware executes many DMA transfer. After every transfer I get an
> interrupt and I read some KB (maximum 64KB) of trasferred data.
>
> What I have to do it is to join all DMA transfer in one big user buffer and
> signal an event to user application when buffer is full. This way user will
> see one big buffer (this is required by project specifications I'm working)
> and will process it.

Ah, that is much better! There is no reason to map and lock the entire buffer;
only the 64KB portions that have active requests against them. What you should
probably do in your application, is loop sending a read request for a 64KB chunk
of the buffer, when the request is complete, and then queue up a new request.
In the driver, set the DO_DIRECT_IO bit in the device object (assuming you want
to use ReadFile to get the data). The I/O manager will map and lock the 64KB
region for you, and create the MDL. In your Start I/O routine, create your
scatter-gather list and program the DMA controller.

> Looking in MSDN (Q191840 and Q194945) I found "section objects": the idea is
> to create a section in user mode with CreateFileMapping and use
> ZwOpenSection to open it in kernel mode. The only thing I cannot understand
> from documentation it is if this way I use memory or Paging file. What do
> you think about ?

Nope. You have no need of that here. The method I outlined above is the
standard way of doing such things

-Brian

Brian Catlin, Sannas Consulting 310-944-9492
Windows Network, Video, WDM Device Driver Training & Consulting
See WWW.AZIUS.COM.bad for courses and scheduling
REMOVE .BAD FROM EMAIL AND WEB ADDRESS

> Thank a lot,
> Blu
>
> "Brian Catlin" <brianc@sannas.org.bad> ha scritto nel messaggio
> news:%23I4DIcP7DHA.2676@TK2MSFTNGP10.phx.gbl...
> > "blu" <b.lu@fastwebnet.it> wrote in message
> > news:%23L7UShM7DHA.2480@TK2MSFTNGP12.phx.gbl...
> > > Hi,
> > > how to share a very large buffer (i.e. about 500 MB, megabytes !!)
> between
> > > user Memory and Kernel Memory ?
> >
> > Does it really need to be shared? Or, does it just need to be written by
> a DMA
> > engine on a controller?
> >
> > > I allocate a buffer in user mode (with c++ new operator) and I pass the
> > > pointer to my driver with an IOCTL.
> > > Then I want to fill this memory with some data.
> > > Data come from a DMA transfer, so I fill user buffer when I receive DMA
> done
> > > interrupt.
> > >
> > > If I use user pointer I get a system crash after some KB.
> >
> > Sure, the buffer may be virtually contiguous, but it is certainly not
> physically
> > contiguous.
> >
> > > If I use MDL I cannot use use buffer larger about than 50MB (if size is
> too
> > > large i get exception).
> >
> > Actually, I believe an MDL can map 64MB. Of course, you can chain a
> series of
> > MDLs together, but you will have to do that yourself.
> >
> > >
> > > Some other ideas to make many DMA data pieces available to user as a
> large
> > > buffer ?
> >
> > Side stepping for a moment the advisability of locking down 500MB of
> memory for
> > a DMA transfer, what you need to do is implement what is called 'Neither
> I/O',
> > which means the I/O manager will not do any pre-processing or
> post-processing of
> > the I/O requests for you - you have to do it all. The simplest way to
> implement
> > 'Neither I/O' is to use a Device I/O Control (you could also just use
> ReadFile,
> > but don't set either DO_DIRECT_IO or DO_BUFFERED_IO in your device object
> flags;
> > of course, all your READs and WRITEs to the device will then be 'Neither
> I/O',
> > which is why I recommend using a Device I/O Control), and then in the
> dispatch
> > routine lock down the pages and build your MDL chain. Once that's done,
> the IRP
> > should then be passed to IoStartPacket. When the IRP reaches your Start
> I/O
> > routine, then build your scatter gather list and program your DMA engine.
> When
> > you complete the IRP in your DPC routine, the I/O manager will
> automatically
> > unlock and deallocate the MDL chain.
> >
> > Are you sure that you REALLY need to lock down 500MB for a *single* DMA
> > transfer? If you don't have upwards of a gigabyte of physical memory this
> will
> > be very inconvenient. Is it a hardware requirement that you do 500MB
> transfers?
> > Unless it is very special hardware, it seems like a very poor design. Try
> and
> > break the transfer up into a series of smaller transfers.
> >
> > -Brian
> >
> > Brian Catlin, Sannas Consulting 310-944-9492
> > Windows Network, Video, WDM Device Driver Training & Consulting
> > See WWW.AZIUS.COM.bad for courses and scheduling
> > REMOVE .BAD FROM EMAIL AND WEB ADDRESS
> >
> >
>
>



Re: Sharing very large buffer between User and Kernel by r_konjeti

r_konjeti
Sun Feb 08 16:15:02 CST 2004

I have similar issue. I can receive packet of any size(4 bytes to 4096
bytes) from kernel to user. I want to use 5 buffers of 20K bytes. Most
of the time these buffers of 20K take only 100 to 4K bytes from kernel
to user mode. But when too many packets and buffers cant supply to
user mode, kernel queues them and this is when this 20K size helps (to
supply 10 packets or more during busy time). This works because it is
very good in busy time, but is overkill when just receiving 1 small
packet. How can I optimize 20k buffer to carry 100 bytes from kernel
to user mode every 10 seconds asynchronous. And this is not stream.

Any suggestions. When I am completing Irp, I use correct length. But
when I am sending 20K Irp from user mode to kernel mode, I cant think
anyway to optimise.

Thanks a lot.