Article ID: 189327 - View products that this article applies to.
This article was previously published under Q189327
When you map a large amount of adapter memory, you may receive one of the following symptoms:
Introduction to Page Table Entries (PTE)Every process that runs on a Windows NT system has a 4 GB virtual address ranging from 0x00000000 to 0xFFFFFFFF for its use. Of this, the upper 2 GB address ranging from 0x8000000 to 0xFFFFFFFF is common to all processes running in the system, and it is called kernel or system address space. The lower region ranging from 0x00000000 to 0x7FFFFFFF is called user address space.
From the process perspective, each element of virtual address conceptually refers to a byte of physical memory. It is the responsibility of the Virtual Memory Manager (VMM) in conjunction with processor memory manager unit (MMU) to translate or map each virtual address into a corresponding physical address. The VMM performs the mapping by dividing the RAM into fixed-size page frames, creating page tables to store information about these page frames, and mapping them. Each PTE represents a page frame and contains information necessary for the VMM to locate a page.
On an x86-based system that uses a 4-KB page size, the maximum number of PTEs required to map 2 GB of address space is 524,288 (2 GB/4 KB). On a typical system, this space is used as follows:
The system uses these PTEs to create kernel thread stacks, load device drivers (and their DLLs), to map system virtual address space for I/O transfers or callers of MmMapIoSpace/MmMapLockedPages/ MmGetSystemAddressForMdl/MmAllocateNonCachedMemory, and for other miscellaneous purposes. This system PTE pool can become heavily used and heavily fragmented. This means that your driver might not be able to get enough contiguous virtual address space from the system PTE pool at any given time, even though the total address space still remaining in it might be large enough.
It also means that if your driver uses up system PTE pool entirely, other parts of the system will degrade, even resulting in threads not being created, system stalls, and outright bug checks (because some drivers call allocate-system-memory with the MustSucceed parameter set).
You must be extremely careful when using this pool-only map. Use the portions of the adapter RAM that you really need system access to from any process context, and map only the amount that you need. Do not map the whole adapter range if you do not really need to access it all from system mode.
IMPORTANT: Unmap the memory as soon as you are finished in the right process context. Otherwise, the system will run out of PTEs, and it will bug check. You can increase the default number of PTEs-calculated based on the total system memory-up to a maximum value by adding a number (equal to the number of pages to be increased) to the registry at:
You can also monitor currently available "Free System Page Table Entries" using Performance Monitor.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager \Memory Management\SystemPages
NOTE: The adapter memory pages are not used for page replacement. They remain mapped into the process's address space even if the process is idle or entirely swapped out.
Following are the two most common ways to map adapter memory. The first method maps the memory directly into the process's user-space, and the second method maps into process's system-space and optionally into user- space. Both of these methods require the physical memory to be contiguous. Because of the PTE limitation, you might not be able to map a large amount of memory in system-space. However, you might be able to map into the user- space if it is not fragmented or used up.
Section Object MethodThere is a sample (MAPMEM) in the Windows NT 4.0 DDK (available through MSDN Professional membership) that shows how to perform this mapping. Here is an outline of the technique:
NOTE: In general, it can be dangerous to use the ZwMapViewOfSection using \Device\PhysicalMemory unless you already own the physical pages. A driver that maps pages that it does not own almost always causes memory corruption because the owner can change the page attributes, free the pages, and make other changes. Drives should map only the memory that they own. Also, it is strictly illegal to map a physical address concurrently with two different attributes (that is, cached vs noncached vs writecombined). Doing this causes processor TLB corruption and unpredictable results.
On WindowsXP, the ZwMapViewOfSection function returns STATUS_CONFLICTING_ADDRESSES error if drivers try to map the same physical address concurrently with conflicting attributes.
MmMapIoSpace MethodThis method shows how to map memory in the process system address space and in the process user address space.
199311The advantage of this method is that you get SystemVirtualAddress, which can be used in any process context (such as DPCs and ISR), and an UserVirtualAddress that can be used by the user-mode application in whose context it is mapped.
(http://support.microsoft.com/kb/199311/EN-US/ )INFO: MmMapLockedPages Returns Actual Virtual Address in SP4
If you map into system address space, you should unmap as follows:
If you map into user address space, you should unmap as follows only while running in the context of the process in which you mapped the memory:
For more information, see the Windows NT 4.0 DDK documentation, or "Inside Windows NT" by Helen Custer (Microsoft Press 1993).
Article ID: 189327 - Last Review: March 7, 2005 - Revision: 1.2