From: mirage2k2 on
The documentation on MmAllocateContiguousMemory says that it attempts to
allocate memory from the non-paged pool, and if this fails then "it attempts
to perform the allocation from available unused pages".

Firstly, what on earth does that mean? Secondly, will the memory "from
available unused pages" still be non-paged? I will be accessing it at
DISPATCH_LEVEL so I need to be certain.

My guess is that the memory available in "unused pages" is somehow mapped
into the non-paged pool ... thus increasing the size of the pool.


My next question is about the size of the non-paged pool. I've read a few
articles that suggest that there is a limit of 250MB, irrespective of total
RAM. Does anyone know if there is a way of changing the configuration of
the system to make this value higher, i.e. some weird registry setting or
some system API call.

Basically I need to allocate between 32MB - 64MB of non-paged memory, at any
given time, and I need it to work. Allocating the memory in DriverEntry at
startup is probably my best shot but there will be times when I don't need to
allocate anything at all ... I don't want to allocate 32MB and then never use
it ... or hog it until I do need it.

Does anyone have any ideas?
Thanks
Mirage2k

From: Tim Roberts on
mirage2k2 <mirage2k2(a)discussions.microsoft.com> wrote:
>
>The documentation on MmAllocateContiguousMemory says that it attempts to
>allocate memory from the non-paged pool, and if this fails then "it attempts
>to perform the allocation from available unused pages".
>
>Firstly, what on earth does that mean? Secondly, will the memory "from
>available unused pages" still be non-paged? I will be accessing it at
>DISPATCH_LEVEL so I need to be certain.

The current documentation does not make that statement. Yes,
MmAllocateContiguousMemory will always allocate non-paged memory.

>My next question is about the size of the non-paged pool. I've read a few
>articles that suggest that there is a limit of 250MB, irrespective of total
>RAM.

Depends on the operating system. In some versions, the total amount
depends on the size of the RAM, but the upper limit is approximately what
you describe.

>Does anyone know if there is a way of changing the configuration of
>the system to make this value higher, i.e. some weird registry setting or
>some system API call.

Nope.

>Basically I need to allocate between 32MB - 64MB of non-paged memory, at any
>given time, and I need it to work. Allocating the memory in DriverEntry at
>startup is probably my best shot but there will be times when I don't need to
>allocate anything at all ... I don't want to allocate 32MB and then never use
>it ... or hog it until I do need it.

If you absolutely need it, then allocate it in DriverEntry and fail the
call if you can't get it. Physical memory gets more and more fragmented as
the system continues to run. It doesn't take very long for chaos to take
over, so that dozens of megabytes are simply not available.
--
Tim Roberts, timr(a)probo.com
Providenza & Boekelheide, Inc.
From: David Schwartz on
On Mar 2, 8:32 pm, mirage2k2 <mirage...(a)discussions.microsoft.com>
wrote:

> The documentation on MmAllocateContiguousMemory says that it attempts to
> allocate memory from the non-paged pool, and if this fails then "it attempts
> to perform the allocation from available unused pages".
>
> Firstly, what on earth does that mean?

Exactly what it says. The non-paged pool is tried first, but if it's
empty, unused pages are used.

> Secondly, will the memory "from
> available unused pages" still be non-paged?  I will be accessing it at
> DISPATCH_LEVEL so I need to be certain.

Yes.

> My guess is that the memory available in "unused pages" is somehow mapped
> into the non-paged pool ... thus increasing the size of the pool.

Nope. Because the memory is allocated directly from unused pages, it
never technically becomes part of the non-paged pool. But the logical
effect is the same as if the non-paged pool were grown and then the
pages were allocated from it.

> My next question is about the size of the non-paged pool.  I've read a few
> articles that suggest that there is a limit of 250MB, irrespective of total
> RAM.   Does anyone know if there is a way of changing the configuration of
> the system to make this value higher, i.e. some weird registry setting or
> some system API call.

http://blogs.technet.com/markrussinovich/archive/2009/03/26/3211216.aspx
It's not 250MB any more.

> Basically I need to allocate between 32MB - 64MB of non-paged memory, at any
> given time, and I need it to work.  Allocating the memory in DriverEntry at
> startup is probably my best shot but there will be times when I don't need to
> allocate anything at all ... I don't want to allocate 32MB and then never use
> it ... or hog it until I do need it.

I would strongly advise you to hog the whole 64MB immediately and
never let it go. Physical memory tends to get fragmented and the odds
of being able to allocate 64MB of contiguous physical memory later on
are not good.

DS
From: Maxim S. Shatskih on
> The documentation on MmAllocateContiguousMemory

Forget this call at all.

The only need in _contiguous_ memory is for DMA, and, for DMA, you must use ->AllocateCommonBuffer.

MmAllocateContiguousMemory is only provided for DMA adapter object implementations to implement ->AllocateCommonBuffer (it usually just calls MmAllocateContiguousMemory with proper parameters).

This is not a general memory allocation routine.

--
Maxim S. Shatskih
Windows DDK MVP
maxim(a)storagecraft.com
http://www.storagecraft.com

From: alberto on

I would just read http://msdn.microsoft.com/en-us/library/ms801986.aspx,
it has all the information you need. Here's my experience,

1. Your only guarantee is that the space is both physically and
logically contiguous,
2. Once you own the physical memory, you can always remap it any way
you want,
3. Sometimes you may get away by fixing the user buffer to physical
memory, mapping it into kernel space, and DMAing directly from it,
4. I may be wrong, but I wouldn't swear by the statement that
nonpaged pool allocations larger than one page are physically
contiguous,
5. I don't know about the nonpaged pool, but my driver sometimes
allocates hundreds of megabytes of contiguous physical memory without
a problem,
6. If you don't grab that memory at start time, chances are that you
won't get it after a long enough period of time,
7. Grab your physical memory at start time, not at DriverEntry time,
8. You may run out of kernel-side address space before you run out
of physical memory.

What I do is, I grab a sizeable chunk of physically contiguous memory
at driver start time, and I suballocate space from it as my DMA needs
it. I do it at start time, when I handle the Start IRP; doing it at
DriverEntry time may be too early, because you may need data from your
hardware to figure out how large a buffer pool you will need: for
example, I need more memory if I have a quad-core board than if I only
have a one-core board, and I need even more if I have two, four, or
even six boards in the system; and that information isn't available
until start time.

One thing you must watch out is, sometimes you may run out of address
space before you run out of physical memory, specially in 32-bit on a /
3Gb configuration. For example, sometimes I do DMA directly from user
space, when the user buffer is well-behaved enough; if I map user
space to a kernel side address range, sometimes my kernel-side address
space gets pretty crowded. Sometimes your call to
MmAllocateContiguousMemory fails not because you've run out of memory,
but because you've run out of page slots!

Also, I use MmAllocateContiguousMemorySpecifyCache: gives you more
flexibility, you may not need that your memory is cached.

One more thing: if you can afford it, put a Registry entry or two in
your driver, so that you can configure it without having to rebuild.

Hope this helps,


Alberto.



On Mar 2, 11:32 pm, mirage2k2 <mirage...(a)discussions.microsoft.com>
wrote:
> The documentation on MmAllocateContiguousMemory says that it attempts to
> allocate memory from the non-paged pool, and if this fails then "it attempts
> to perform the allocation from available unused pages".
>
> Firstly, what on earth does that mean?  Secondly, will the memory "from
> available unused pages" still be non-paged?  I will be accessing it at
> DISPATCH_LEVEL so I need to be certain.

>
> My guess is that the memory available in "unused pages" is somehow mapped
> into the non-paged pool ... thus increasing the size of the pool.
>
> My next question is about the size of the non-paged pool.  I've read a few
> articles that suggest that there is a limit of 250MB, irrespective of total
> RAM.   Does anyone know if there is a way of changing the configuration of
> the system to make this value higher, i.e. some weird registry setting or
> some system API call.
>
> Basically I need to allocate between 32MB - 64MB of non-paged memory, at any
> given time, and I need it to work.  Allocating the memory in DriverEntry at
> startup is probably my best shot but there will be times when I don't need to
> allocate anything at all ... I don't want to allocate 32MB and then never use
> it ... or hog it until I do need it.
>
> Does anyone have any ideas?
> Thanks
> Mirage2k