MmAllocateContiguousMemorySpecifyCache always fail in windows 7

Hi All,

I have inserted 4 PCI cards in my system, system memory is 1GB.
I used MmAllocateContiguousMemorySpecifyCache for getting DMA-able memory.
Each card need 15MB,this success in previous OS’s(i.e. 2000, 2003 server, XP, Vista).
But in windows 7,this failed even I restart the computer.

But I added up to 2GB memory in my computer,this successed.
All the 4 chip can have a 15MB contiguous, cache-aligned memory,
no yellow exclamation point next to our device in Device Manager.

It seems that the memory management scheme of Windows 7 has changed.
When using the call MmAllocateContiguousMemorySpecifyCache(),
less contiguous memory is available when memory is not large enough.(i.e.1GB)

How to fix this? (the method that without adding memory in system)
does anyone know what changed in Windows 7 and why?

Any help is appreciated.Thanks.

Best Regards
Zhou ChengJun

> I have inserted 4 PCI cards in my system, system memory is 1GB.

I used MmAllocateContiguousMemorySpecifyCache for getting DMA-able memory.

Use ->AllocateCommonBuffer instead, it is more correct.

How to fix this? (the method that without adding memory in system)
does anyone know what changed in Windows 7 and why?

Probably no ways.

Instead, allocate using MmAllocatePagesForMdl, then create the SGL for this MDL, and use this discontiguous SGL instead of the contiguous common buffer.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

I need specify a nonzero value for the BoundaryAddressMultiple parameter.
In this case, AllocateCommonBuffer can not instead in my opinion.

So I need add up to 2GB+ memory in my computer if I want to use win 7?

Why windows 7 do this?
less contiguous memory is available when memory is not large enough.

> It seems that the memory management scheme of Windows 7 has changed.

When using the call MmAllocateContiguousMemorySpecifyCache(),
less contiguous memory is available when memory is not large
enough.(i.e.1GB)

How to fix this? (the method that without adding memory in system)
does anyone know what changed in Windows 7 and why?

One possibility might be that something changed in the boot order which
caused memory to become more fragmented by the time your driver
loads. You can try comparing the output of !vm at the point where you
allocate memory on Vista and Win7 to see if anything stands out.


Pavel Lebedinsky/Windows Kernel Test
This posting is provided “AS IS” with no warranties, and confers no rights.

>Why windows 7 do this?
Do you allocate memory during initialization?
It is logical behavior of Windows. I believe, 1G is a minimal required RAM for
Windows 7. Others version of Windows have different requirements for installed RAM.
You could solve this problem in a very simple way. Organize a loop where you allocate memory for your devices. You could start to allocate 15M for each device. If you will fail, you could reduce size of required memory on a predefined number and try to allocate again. Your loop will continue until you succeed. This is allow to you never fail and to obey of using memory resources which is shared among all Windows components and others drivers.

Igor Sharovar

>You can try comparing the output of !vm at the point where …

I installed the driver and then reboot.
(windows xp,4 chips are ok, no yellow exclamation point appeared
windows 7,only one chip is ok,other 3 chips have yellow exclamation point in Device Manager)

!vm result is as following:
windows xp–

lkd> !vm

*** Virtual Memory Usage ***
Physical Memory: 261900 ( 1047600 Kb)
Page File: ??\C:\pagefile.sys
Current: 1572864 Kb Free Space: 1525828 Kb
Minimum: 1572864 Kb Maximum: 3145728 Kb
Available Pages: 116627 ( 466508 Kb)
ResAvail Pages: 164880 ( 659520 Kb)
Locked IO Pages: 88 ( 352 Kb)
Free System PTEs: 130874 ( 523496 Kb)
Free NP PTEs: 32767 ( 131068 Kb)
Free Special NP: 24723 ( 98892 Kb)
Modified Pages: 6049 ( 24196 Kb)
Modified PF Pages: 5958 ( 23832 Kb)
NonPagedPool Usage: 8940 ( 35760 Kb)
NonPagedPool Max: 52997 ( 211988 Kb)
PagedPool 0 Usage: 10106 ( 40424 Kb)
PagedPool 1 Usage: 818 ( 3272 Kb)
PagedPool 2 Usage: 828 ( 3312 Kb)
PagedPool 3 Usage: 814 ( 3256 Kb)
PagedPool 4 Usage: 814 ( 3256 Kb)
PagedPool Usage: 13380 ( 53520 Kb)
PagedPool Maximum: 40960 ( 163840 Kb)
Shared Commit: 2527 ( 10108 Kb)
Special Pool: 368 ( 1472 Kb)
Shared Process: 3220 ( 12880 Kb)
PagedPool Commit: 13380 ( 53520 Kb)
Driver Commit: 3689 ( 14756 Kb)
Committed pages: 130037 ( 520148 Kb)
Commit limit: 629978 ( 2519912 Kb)

windows 7–

lkd> !vm

*** Virtual Memory Usage ***
Physical Memory: 261918 ( 1047672 Kb)
Page File: ??\E:\pagefile.sys
Current: 1048576 Kb Free Space: 1023084 Kb
Minimum: 1048576 Kb Maximum: 4194304 Kb
unable to get nt!MmSystemLockPagesCount
Available Pages: 139284 ( 557136 Kb)
ResAvail Pages: 213094 ( 852376 Kb)
Locked IO Pages: 0 ( 0 Kb)
Free System PTEs: 390466 ( 1561864 Kb)
Modified Pages: 8925 ( 35700 Kb)
Modified PF Pages: 8918 ( 35672 Kb)
NonPagedPool Usage: 3452 ( 13808 Kb)
NonPagedPool Max: 189695 ( 758780 Kb)
PagedPool 0 Usage: 17135 ( 68540 Kb)
PagedPool 1 Usage: 3297 ( 13188 Kb)
PagedPool 2 Usage: 0 ( 0 Kb)
PagedPool 3 Usage: 0 ( 0 Kb)
PagedPool 4 Usage: 23 ( 92 Kb)
PagedPool Usage: 20455 ( 81820 Kb)
PagedPool Maximum: 523264 ( 2093056 Kb)
Session Commit: 8779 ( 35116 Kb)
Shared Commit: 24230 ( 96920 Kb)
Special Pool: 0 ( 0 Kb)
Shared Process: 1815 ( 7260 Kb)
PagedPool Commit: 20456 ( 81824 Kb)
Driver Commit: 3605 ( 14420 Kb)
Committed pages: 156953 ( 627812 Kb)
Commit limit: 524062 ( 2096248 Kb)

Can we get some useful information by comparing the two results?
Thank you.

>If you will fail, you could reduce size of required memory on a
predefined number

The size of required memory is 15MB,fixed.
So it is still failed.

>The size of required memory is 15MB,fixed. So it is still failed.
Do you mean that you reduce size of allocated memory and still fail?
If so, you need to reduce the size of memory until you will succeed.
I also recommend to publish !vm results for two cases - before calling MmAllocateContiguousMemorySpecifyCache and when you fail.

Igor Sharovar

> !vm result is as following:

windows xp–
lkd> !vm

windows 7–
lkd> !vm

Can we get some useful information by comparing the two results?

Not from these two results. We need to see and compare the state of the
system at the point where you call MmAllocateContiguousMemory, not
at some point in the future.

Also, comparing Vista (SP1 or SP2) and Win7 would be more useful
because the internals of MmAllocateContiguousMemory changed
dramatically in Vista SP1.


Pavel Lebedinsky/Windows Kernel Test
This posting is provided “AS IS” with no warranties, and confers no rights.

>Do you mean that you reduce size of allocated memory and still fail?
When I reduce the size of allocated memory to 8MB,it is Ok.
But the size I need is 15MB,8MB is not insufficient.

>We need to see and compare the state of the
system at the point where you call MmAllocateContiguousMemory

In windows 7
Before MmAllocateContiguousMemory is:
lkd> !vm

*** Virtual Memory Usage ***
Physical Memory: 261918 ( 1047672 Kb)
Page File: ??\E:\pagefile.sys
Current: 1048576 Kb Free Space: 950648 Kb
Minimum: 1048576 Kb Maximum: 4194304 Kb
unable to get nt!MmSystemLockPagesCount
Available Pages: 141185 ( 564740 Kb)
ResAvail Pages: 216385 ( 865540 Kb)
Locked IO Pages: 0 ( 0 Kb)
Free System PTEs: 404246 ( 1616984 Kb)
Modified Pages: 13574 ( 54296 Kb)
Modified PF Pages: 13373 ( 53492 Kb)
NonPagedPool Usage: 3380 ( 13520 Kb)
NonPagedPool Max: 189695 ( 758780 Kb)
PagedPool 0 Usage: 17157 ( 68628 Kb)
PagedPool 1 Usage: 2706 ( 10824 Kb)
PagedPool 2 Usage: 67 ( 268 Kb)
PagedPool 3 Usage: 82 ( 328 Kb)
PagedPool 4 Usage: 92 ( 368 Kb)
PagedPool Usage: 20104 ( 80416 Kb)
PagedPool Maximum: 523264 ( 2093056 Kb)
Session Commit: 8800 ( 35200 Kb)
Shared Commit: 27272 ( 109088 Kb)
Special Pool: 0 ( 0 Kb)
Shared Process: 1842 ( 7368 Kb)
PagedPool Commit: 20104 ( 80416 Kb)
Driver Commit: 3694 ( 14776 Kb)
Committed pages: 177293 ( 709172 Kb)
Commit limit: 524062 ( 2096248 Kb)

Total Private: 98337 ( 393348 Kb)
0eb8 svchost.exe 13118 ( 52472 Kb)

After calling MmAllocateContiguousMemory,and it failed:
lkd> !vm

*** Virtual Memory Usage ***
Physical Memory: 261918 ( 1047672 Kb)
Page File: ??\E:\pagefile.sys
Current: 1048576 Kb Free Space: 884124 Kb
Minimum: 1048576 Kb Maximum: 4194304 Kb
unable to get nt!MmSystemLockPagesCount
Available Pages: 166179 ( 664716 Kb)
ResAvail Pages: 216493 ( 865972 Kb)
Locked IO Pages: 0 ( 0 Kb)
Free System PTEs: 388338 ( 1553352 Kb)
Modified Pages: 10115 ( 40460 Kb)
Modified PF Pages: 9737 ( 38948 Kb)
NonPagedPool Usage: 4142 ( 16568 Kb)
NonPagedPool Max: 189695 ( 758780 Kb)
PagedPool 0 Usage: 19108 ( 76432 Kb)
PagedPool 1 Usage: 3173 ( 12692 Kb)
PagedPool 2 Usage: 653 ( 2612 Kb)
PagedPool 3 Usage: 725 ( 2900 Kb)
PagedPool 4 Usage: 661 ( 2644 Kb)
PagedPool Usage: 24320 ( 97280 Kb)
PagedPool Maximum: 523264 ( 2093056 Kb)
Session Commit: 8887 ( 35548 Kb)
Shared Commit: 27102 ( 108408 Kb)
Special Pool: 0 ( 0 Kb)
Shared Process: 1989 ( 7956 Kb)
PagedPool Commit: 24324 ( 97296 Kb)
Driver Commit: 3728 ( 14912 Kb)
Committed pages: 185418 ( 741672 Kb)
Commit limit: 524062 ( 2096248 Kb)

Total Private: 102737 ( 410948 Kb)
0eb8 svchost.exe 13370 ( 53480 Kb)

> In windows 7

Before MmAllocateContiguousMemory is:
lkd> !vm

After calling MmAllocateContiguousMemory,and it failed:
lkd> !vm

Since you’re using lkd here it means the system has already finished
booting and has been running for some time. In this case, I’m not
surprised 15 MB allocations are failing; in fact, I would expect them
to fail on Vista as well.

To get meaningful data for comparing Vista and win7, you need to
instrument the driver to issue DbgBreakPoint() immediately before
the MmAllocateContiguousMemory call (alternatively you could
set a breakpoint on MmAllocateContiguousMemorySpecifyCache
but then you might have to step over unrelated calls from other
components). Take two systems with identical hardware, one
running win7 RTM and the other Vista SP1 or SP2. Hook them to
real kd using serial/1394 and when the driver breaks in during boot,
run !vm and capture the full output (inlcuding which processes are
running). Then hit ‘gu’ and make sure the request fails on win7 and
succeeds on Vista (the result of the call will be in the EAX/RAX
register). Then post the full !vm output for both Vista and win7 here.


Pavel Lebedinsky/Windows Kernel Test
This posting is provided “AS IS” with no warranties, and confers no rights.

Another thing that might be useful in additon to !vm is the value of
MmMdlPagesAllocated:

kd> dd nt!MmMdlPagesAllocated l1


Pavel Lebedinsky/Windows Kernel Test
This posting is provided “AS IS” with no warranties, and confers no rights.

>To get meaningful data for comparing Vista and win7…

Thank you,I’ll try this.