xxxxx@yahoo.com wrote:
Yes, sorry I should have clarified that it is the Virtual memory which needs to be contiguous for my purposes.
Then forget about AllocateCommonBuffer entirely, and just use
ExAllocatePool. AllocateCommonBuffer is needed only in very specific
circumstances.
Even then, however, 128MB is a honking big allocation. Is there a
reason you can’t do it once when your driver loads and then keep it
around forever? Or is that what you are doing?
Calling the AllocateCommonBuffer multiple times to get the virtual addresses is easy to do. But I need a way to make these addresses contiguous. That aside, I’m still confused as to why the AllocateCommonBuffer routine was able to allocate 128 MBytes of memory the first time, but when I free up that memory it takes a while to re-allocate it again.
Consider how dynamic your virtual memory space is. If you watch
performance monitor, you’ll often see hundreds or thousands of page
faults per second. Each one of those page faults has to readjust the
virtual memory state – swap something out, allocate new empty pages,
etc. Also remember that unused physical memory is wasted memory.
Windows naturally tries to use as much of your physical memory as
possible. If you are running 10 active processes at once, there are
parts of all 10 of those processes in physical memory at once. Only one
process is active in virtual memory, but the physical pages are still
there until they are needed for something else.
Because of that, physical memory gets wildly fragmented very early on.
If you look at physical memory, page 48901 might be assigned to a DLL in
process 16. Page 48902 might be free. Page 48903 might be part of a
kernel driver. Page 48904 might be free. Page 48905 might be assigned
to the disk cache. Page 48906 might be free. In that scenario,
although there are 8192 bytes in free pages, there’s only 4096 bytes of
contiguous space. Because of the magic of virtual memory, physical
fragmentation is completely unimportant, except for drivers that need
common buffers for DMA.
As long as things haven’t been “stirred up” very much, your driver can
find 128MB free. When you release that memory, what if the algorithm
puts those freed pages right to the top of the free list? The next
allocation would take a chunk of that, and now there isn’t 128MB free
any more. In order to get that space, the system has to wait until that
much space is available. It can’t do that by tweaking the page tables
– it actually has to copy memory from one place to another, and the
owning process has to be idle.
If the truth be told, I’m surprised at your description. I thought
AllocateCommonBuffer would simply fail in that case. I didn’t think the
system actually tried to rebalance resources to satisfy the allocation.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.