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?re... ============================================================================== --- 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?r... ============================================================================== --- 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) {