[NTOS]: MxGetNextPage is not platform-specific, so share it.
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 10 Feb 2010 17:42:07 +0000 (17:42 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 10 Feb 2010 17:42:07 +0000 (17:42 +0000)
[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.

svn path=/trunk/; revision=45556

reactos/ntoskrnl/mm/ARM3/i386/init.c
reactos/ntoskrnl/mm/ARM3/miarm.h
reactos/ntoskrnl/mm/ARM3/mminit.c

index 47321ea..3fcb081 100644 (file)
 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)
+    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))
     {
-        //
-        // Crash the system
-        //
-        KeBugCheckEx(INSTALL_MORE_MEMORY,
-                     MmNumberOfPhysicalPages,
-                     MxFreeDescriptor->PageCount,
-                     MxOldFreeDescriptor.PageCount,
-                     PageCount);
+        /* Force the non paged pool to be 2MB so we can reduce RAM usage */
+        MmSizeOfNonPagedPoolInBytes = 2 * _1MB;
     }
     
-    //
-    // Use our lowest usable free pages
-    //
-    Pfn = MxFreeDescriptor->BasePage;
-    MxFreeDescriptor->BasePage += PageCount;
-    MxFreeDescriptor->PageCount -= PageCount;
-    return Pfn;
+    /* 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 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     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 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     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 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     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 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     //
     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
index 77e7847..05fab8b 100644 (file)
@@ -198,6 +198,12 @@ MiInitMachineDependent(
     IN PLOADER_PARAMETER_BLOCK LoaderBlock
 );
 
+PFN_NUMBER
+NTAPI
+MxGetNextPage(
+    IN PFN_NUMBER PageCount
+);
+
 PPHYSICAL_MEMORY_DESCRIPTOR
 NTAPI
 MmInitializeMemoryLimits(
index ea1a60f..1d024d3 100644 (file)
@@ -259,6 +259,30 @@ MiSyncARM3WithROS(IN PVOID AddressStart,
     }
 }
 
+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,