I am writing an NT4.0 device driver for an application that will allocate
many many 8Meg buffers. The PCI device is going to do hardware busmaster
DMA directly to these application buffers. The throughput is high, so the
buffers cannot be paged out to the harddrive. How does the application (or
my driver) prevent these buffers from ever being paged out?
Thanks,
Doug Hoyt
>I am writing an NT4.0 device driver for an application that will allocate
many many 8Meg buffers. The PCI device is going to do hardware busmaster
DMA directly to these application buffers. The throughput is high, so the
buffers cannot be paged out to the harddrive. How does the application (or
my driver) prevent these buffers from ever being paged out?
Generally, application (user mode) memory is fully pagable. You can suggest
to the OS it not page things out, by increasing your app’s working set. You
could also just allocate a bunch of user mode memory, and pass it down to
an overlapped I/O call. You driver then page locks the memory and returns
the operation pending. You can then eventually unlock the memory, and
complete the IRP.
I suppose you also could never complete the IRP (completion at handle
close), and inform the app through some other means when buffers are filled
(like events) and some queue data structures shared between your app and
driver. A plus of this would be you could build the physical address
scatter/gather lists ONCE, and just keep stuffing it back into the
hardware. For VERY high performance devices, locking/unlocking pages can
burn some cpu time (and thrashes the TPB). You could also have the driver
allocate the memory, and lock it, and map it into the app’s address space.
To the app, it would open the device and make a special allocation IOCTL
that returned the virtual address of the locked buffer area.
You might also imagine an application that memory maps some file, and
passes the virtual address of this mapped file down to a driver. When the
driver locks the pages, the virtual memory systems reads them from the
file. Or the opposite, the app maps an empty file, pass the address to the
driver, and on I/O completion asks the OS to flush the mapped section to
it’s backing file.
A really exotic case is the app maps some buffers which actually are device
memory on a disk/network controller, and passes those addresses to your
driver. On I/O completion it asks the other device to do it’s thing with
it’s internal buffers. This has the very cool property of making your
device transfer across a PCI bus bypassing main memory. Or maybe your
device should not even do busmaster I/O, and just be a zippy PCI target.
Your app then just maps target memory, and when signaled by your driver
that data has arrived, it passes the address to something like a SCSI
driver, which initiates a bus master transfer from your device target
memory (assuming you have a lot), directly across the PCI bus to a disk.
- Jan
> buffers cannot be paged out to the harddrive. How does the application
(or
my driver) prevent these buffers from ever being paged out?
By allocating the properly from the nonpaged pool
(ExAllocatePool/MmAllocateContiguousMemory/HalAllocateCommonBuffer) OR by
locking them via MmProbeAndLockPages.
Surely, no DMA buffers can be paged - this is a law.
Max