Author: sir_richard
Date: Wed Feb 10 18:42:07 2010
New Revision: 45556
URL:
http://svn.reactos.org/svn/reactos?rev=45556&view=rev
Log:
[NTOS]: MxGetNextPage is not platform-specific, so share it.
[NTOS]: Factor out computations of NP sizes and limits into MiComputeNonPagedPoolVa.
[NTOS]: Fix NP size/limit calculations to use the amount of FREE RAM, not the amount of
INSTALLED RAM.
[NTOS]: Use Windows 2003's algorithm for NP size on machines with more than 512MB of
FREE RAM.
[NTOS]: Partly handle the case of machines with NP over 128MB.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Wed Feb 10 18:42:07 2010
@@ -29,39 +29,133 @@
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
+/* Template PTE and PDE for a kernel page */
MMPTE ValidKernelPde = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1,
.u.Hard.Accessed = 1};
MMPTE ValidKernelPte = {.u.Hard.Valid = 1, .u.Hard.Write = 1, .u.Hard.Dirty = 1,
.u.Hard.Accessed = 1};
+/* Make the code cleaner with some definitions for size multiples */
+#define _1KB (1024)
+#define _1MB (1000 * _1KB)
+
+/* Architecture specific size of a PDE directory, and size of a page table */
+#define PDE_SIZE (4096 * sizeof(MMPDE))
+#define PT_SIZE (1024 * sizeof(MMPTE))
+
/* PRIVATE FUNCTIONS **********************************************************/
-PFN_NUMBER
+VOID
NTAPI
-MxGetNextPage(IN PFN_NUMBER PageCount)
+MiComputeNonPagedPoolVa(IN ULONG FreePages)
{
- PFN_NUMBER Pfn;
-
- //
- // Make sure we have enough pages
- //
- if (PageCount > MxFreeDescriptor->PageCount)
- {
- //
- // Crash the system
- //
- KeBugCheckEx(INSTALL_MORE_MEMORY,
- MmNumberOfPhysicalPages,
- MxFreeDescriptor->PageCount,
- MxOldFreeDescriptor.PageCount,
- PageCount);
- }
-
- //
- // Use our lowest usable free pages
- //
- Pfn = MxFreeDescriptor->BasePage;
- MxFreeDescriptor->BasePage += PageCount;
- MxFreeDescriptor->PageCount -= PageCount;
- return Pfn;
+ IN PFN_NUMBER PoolPages;
+
+ /* Check if this is a machine with less than 256MB of RAM, and no overide */
+ if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING) &&
+ !(MmSizeOfNonPagedPoolInBytes))
+ {
+ /* Force the non paged pool to be 2MB so we can reduce RAM usage */
+ MmSizeOfNonPagedPoolInBytes = 2 * _1MB;
+ }
+
+ /* Hyperspace ends here */
+ MmHyperSpaceEnd = (PVOID)((ULONG_PTR)MmSystemCacheWorkingSetList - 1);
+
+ /* Check if the user gave a ridicuously large nonpaged pool RAM size */
+ if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) > (FreePages * 7 / 8))
+ {
+ /* More than 7/8ths of RAM was dedicated to nonpaged pool, ignore! */
+ MmSizeOfNonPagedPoolInBytes = 0;
+ }
+
+ /* Check if no registry setting was set, or if the setting was too low */
+ if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize)
+ {
+ /* Start with the minimum (256 KB) and add 32 KB for each MB above 4 */
+ MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize;
+ MmSizeOfNonPagedPoolInBytes += (FreePages - 1024) / 256 *
MmMinAdditionNonPagedPoolPerMb;
+ }
+
+ /* Check if the registy setting or our dynamic calculation was too high */
+ if (MmSizeOfNonPagedPoolInBytes > MI_MAX_INIT_NONPAGED_POOL_SIZE)
+ {
+ /* Set it to the maximum */
+ MmSizeOfNonPagedPoolInBytes = MI_MAX_INIT_NONPAGED_POOL_SIZE;
+ }
+
+ /* Check if a percentage cap was set through the registry */
+ if (MmMaximumNonPagedPoolPercent) UNIMPLEMENTED;
+
+ /* Page-align the nonpaged pool size */
+ MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1);
+
+ /* Now, check if there was a registry size for the maximum size */
+ if (!MmMaximumNonPagedPoolInBytes)
+ {
+ /* Start with the default (1MB) */
+ MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool;
+
+ /* Add space for PFN database */
+ MmMaximumNonPagedPoolInBytes += (ULONG)
+ PAGE_ALIGN((MmHighestPhysicalPage + 1) * sizeof(MMPFN));
+
+ /* Check if the machine has more than 512MB of free RAM */
+ if (FreePages >= 0x1F000)
+ {
+ /* Add 200KB for each MB above 4 */
+ MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
+ (MmMaxAdditionNonPagedPoolPerMb / 2);
+ if (MmMaximumNonPagedPoolInBytes < MI_MAX_NONPAGED_POOL_SIZE)
+ {
+ /* Make it at least 128MB since this machine has a lot of RAM */
+ MmMaximumNonPagedPoolInBytes = MI_MAX_NONPAGED_POOL_SIZE;
+ }
+ }
+ else
+ {
+ /* Add 400KB for each MB above 4 */
+ MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
+ MmMaxAdditionNonPagedPoolPerMb;
+ }
+ }
+
+ /* Make sure there's at least 16 pages + the PFN available for expansion */
+ PoolPages = MmSizeOfNonPagedPoolInBytes + (PAGE_SIZE * 16) +
+ ((ULONG)PAGE_ALIGN(MmHighestPhysicalPage + 1) * sizeof(MMPFN));
+ if (MmMaximumNonPagedPoolInBytes < PoolPages)
+ {
+ /* The maximum should be at least high enough to cover all the above */
+ MmMaximumNonPagedPoolInBytes = PoolPages;
+ }
+
+ /* Systems with 2GB of kernel address space get double the size */
+ PoolPages = MI_MAX_NONPAGED_POOL_SIZE * 2;
+
+ /* On the other hand, make sure that PFN + nonpaged pool doesn't get too big */
+ if (MmMaximumNonPagedPoolInBytes > PoolPages)
+ {
+ /* Trim it down to the maximum architectural limit (256MB) */
+ MmMaximumNonPagedPoolInBytes = PoolPages;
+ }
+
+ /* Check if this is a system with > 128MB of non paged pool */
+ if (MmMaximumNonPagedPoolInBytes > MI_MAX_NONPAGED_POOL_SIZE)
+ {
+ /* Check if the initial size is less than the extra 128MB boost */
+ if (MmSizeOfNonPagedPoolInBytes < (MmMaximumNonPagedPoolInBytes -
+ MI_MAX_NONPAGED_POOL_SIZE))
+ {
+ /* FIXME: Should check if the initial pool can be expanded */
+
+ /* Assume no expansion possible, check ift he maximum is too large */
+ if (MmMaximumNonPagedPoolInBytes > (MmSizeOfNonPagedPoolInBytes +
+ MI_MAX_NONPAGED_POOL_SIZE))
+ {
+ /* Set it to the initial value plus the boost */
+ MmMaximumNonPagedPoolInBytes = MmSizeOfNonPagedPoolInBytes +
+ MI_MAX_NONPAGED_POOL_SIZE;
+ }
+ }
+ }
}
NTSTATUS
@@ -71,7 +165,7 @@
PLIST_ENTRY NextEntry;
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
ULONG FreePages = 0;
- PFN_NUMBER PageFrameIndex, PoolPages;
+ PFN_NUMBER PageFrameIndex;
PMMPTE StartPde, EndPde, PointerPte, LastPte;
MMPTE TempPde, TempPte;
PVOID NonPagedPoolExpansionVa;
@@ -79,7 +173,7 @@
PFN_NUMBER FreePage, FreePageCount, PagesLeft, BasePage, PageCount;
/* Check for kernel stack size that's too big */
- if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / 1024))
+ if (MmLargeStackSize > (KERNEL_LARGE_STACK_SIZE / _1KB))
{
/* Sanitize to default value */
MmLargeStackSize = KERNEL_LARGE_STACK_SIZE;
@@ -87,7 +181,7 @@
else
{
/* Take the registry setting, and convert it into bytes */
- MmLargeStackSize *= 1024;
+ MmLargeStackSize *= _1KB;
/* Now align it to a page boundary */
MmLargeStackSize = PAGE_ROUND_UP(MmLargeStackSize);
@@ -219,138 +313,8 @@
//
MxOldFreeDescriptor = *MxFreeDescriptor;
- //
- // Check if this is a machine with less than 256MB of RAM, and no overide
- //
- if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING) &&
- !(MmSizeOfNonPagedPoolInBytes))
- {
- //
- // Force the non paged pool to be 2MB so we can reduce RAM usage
- //
- MmSizeOfNonPagedPoolInBytes = 2 * 1024 * 1024;
- }
-
- //
- // Hyperspace ends here
- //
- MmHyperSpaceEnd = (PVOID)((ULONG_PTR)MmSystemCacheWorkingSetList - 1);
-
- //
- // Check if the user gave a ridicuously large nonpaged pool RAM size
- //
- if ((MmSizeOfNonPagedPoolInBytes >> PAGE_SHIFT) >
- (MmNumberOfPhysicalPages * 7 / 8))
- {
- //
- // More than 7/8ths of RAM was dedicated to nonpaged pool, ignore!
- //
- MmSizeOfNonPagedPoolInBytes = 0;
- }
-
- //
- // Check if no registry setting was set, or if the setting was too low
- //
- if (MmSizeOfNonPagedPoolInBytes < MmMinimumNonPagedPoolSize)
- {
- //
- // Start with the minimum (256 KB) and add 32 KB for each MB above 4
- //
- MmSizeOfNonPagedPoolInBytes = MmMinimumNonPagedPoolSize;
- MmSizeOfNonPagedPoolInBytes += (MmNumberOfPhysicalPages - 1024) /
- 256 * MmMinAdditionNonPagedPoolPerMb;
- }
-
- //
- // Check if the registy setting or our dynamic calculation was too high
- //
- if (MmSizeOfNonPagedPoolInBytes > MI_MAX_INIT_NONPAGED_POOL_SIZE)
- {
- //
- // Set it to the maximum
- //
- MmSizeOfNonPagedPoolInBytes = MI_MAX_INIT_NONPAGED_POOL_SIZE;
- }
-
- //
- // Check if a percentage cap was set through the registry
- //
- if (MmMaximumNonPagedPoolPercent)
- {
- //
- // Don't feel like supporting this right now
- //
- UNIMPLEMENTED;
- }
-
- //
- // Page-align the nonpaged pool size
- //
- MmSizeOfNonPagedPoolInBytes &= ~(PAGE_SIZE - 1);
-
- //
- // Now, check if there was a registry size for the maximum size
- //
- if (!MmMaximumNonPagedPoolInBytes)
- {
- //
- // Start with the default (1MB)
- //
- MmMaximumNonPagedPoolInBytes = MmDefaultMaximumNonPagedPool;
-
- //
- // Add space for PFN database
- //
- MmMaximumNonPagedPoolInBytes += (ULONG)
- PAGE_ALIGN((MmHighestPhysicalPage + 1) * sizeof(MMPFN));
-
- //
- // Add 400KB for each MB above 4
- //
- MmMaximumNonPagedPoolInBytes += (FreePages - 1024) / 256 *
- MmMaxAdditionNonPagedPoolPerMb;
- }
-
- //
- // Make sure there's at least 16 pages + the PFN available for expansion
- //
- PoolPages = MmSizeOfNonPagedPoolInBytes + (PAGE_SIZE * 16) +
- ((ULONG)PAGE_ALIGN(MmHighestPhysicalPage + 1) *
- sizeof(MMPFN));
- if (MmMaximumNonPagedPoolInBytes < PoolPages)
- {
- //
- // Set it to the minimum value for the maximum (yuck!)
- //
- MmMaximumNonPagedPoolInBytes = PoolPages;
- }
-
- //
- // Systems with 2GB of kernel address space get double the size
- //
- PoolPages = MI_MAX_NONPAGED_POOL_SIZE * 2;
-
- //
- // Don't let the maximum go too high
- //
- if (MmMaximumNonPagedPoolInBytes > PoolPages)
- {
- //
- // Set it to the upper limit
- //
- MmMaximumNonPagedPoolInBytes = PoolPages;
- }
-
- //
- // Check if this is a system with > 128MB of non paged pool
- //
- if (MmMaximumNonPagedPoolInBytes > MI_MAX_NONPAGED_POOL_SIZE)
- {
- //
- // FIXME: Unsure about additional checks needed
- //
- DPRINT1("Untested path\n");
- }
+ /* Compute non paged pool limits and size */
+ MiComputeNonPagedPoolVa(FreePages);
//
// Get L2 cache information
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Feb 10 18:42:07 2010
@@ -198,6 +198,12 @@
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
+PFN_NUMBER
+NTAPI
+MxGetNextPage(
+ IN PFN_NUMBER PageCount
+);
+
PPHYSICAL_MEMORY_DESCRIPTOR
NTAPI
MmInitializeMemoryLimits(
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Wed Feb 10 18:42:07 2010
@@ -261,6 +261,30 @@
PFN_NUMBER
NTAPI
+MxGetNextPage(IN PFN_NUMBER PageCount)
+{
+ PFN_NUMBER Pfn;
+
+ /* Make sure we have enough pages */
+ if (PageCount > MxFreeDescriptor->PageCount)
+ {
+ /* Crash the system */
+ KeBugCheckEx(INSTALL_MORE_MEMORY,
+ MmNumberOfPhysicalPages,
+ MxFreeDescriptor->PageCount,
+ MxOldFreeDescriptor.PageCount,
+ PageCount);
+ }
+
+ /* Use our lowest usable free pages */
+ Pfn = MxFreeDescriptor->BasePage;
+ MxFreeDescriptor->BasePage += PageCount;
+ MxFreeDescriptor->PageCount -= PageCount;
+ return Pfn;
+}
+
+PFN_NUMBER
+NTAPI
MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PBOOLEAN IncludeType)
{