Author: tkreuzer Date: Wed Jul 28 23:44:24 2010 New Revision: 48345
URL: http://svn.reactos.org/svn/reactos?rev=48345&view=rev Log: [NTOS] Implement MiScanMemoryDescriptors, that loops all memory allocation descriptors early in Mm initialization and saves a number of values in global variables, instead of doing so in architecture specific code (20% less code here) and repeating the iterations in multiple places. It also initializes an array LocationByMemoryType, that gives us a central place to decide what we want to do with the different memory descriptor types, instead of always checking multiple cases.
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/i386/init.c branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/miarm.h branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/mminit.c branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/i386/init.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Wed Jul 28 23:44:24 2010 @@ -151,9 +151,6 @@ NTAPI MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - PLIST_ENTRY NextEntry; - PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; - ULONG FreePages = 0; PFN_NUMBER PageFrameIndex; PMMPTE StartPde, EndPde, PointerPte, LastPte; MMPTE TempPde, TempPte; @@ -211,122 +208,9 @@ RtlZeroMemory(StartPde, (EndPde - StartPde) * sizeof(MMPTE));
// - // Loop the memory descriptors - // - NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) - { - // - // Get the memory block - // - MdBlock = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - // - // Skip invisible memory - // - if ((MdBlock->MemoryType != LoaderFirmwarePermanent) && - (MdBlock->MemoryType != LoaderSpecialMemory) && - (MdBlock->MemoryType != LoaderHALCachedMemory) && - (MdBlock->MemoryType != LoaderBBTMemory)) - { - // - // Check if BURNMEM was used - // - if (MdBlock->MemoryType != LoaderBad) - { - // - // Count this in the total of pages - // - MmNumberOfPhysicalPages += MdBlock->PageCount; - } - - // - // Check if this is the new lowest page - // - if (MdBlock->BasePage < MmLowestPhysicalPage) - { - // - // Update the lowest page - // - MmLowestPhysicalPage = MdBlock->BasePage; - } - - // - // Check if this is the new highest page - // - PageFrameIndex = MdBlock->BasePage + MdBlock->PageCount; - if (PageFrameIndex > MmHighestPhysicalPage) - { - // - // Update the highest page - // - MmHighestPhysicalPage = PageFrameIndex - 1; - } - - // - // Check if this is free memory - // - if ((MdBlock->MemoryType == LoaderFree) || - (MdBlock->MemoryType == LoaderLoadedProgram) || - (MdBlock->MemoryType == LoaderFirmwareTemporary) || - (MdBlock->MemoryType == LoaderOsloaderStack)) - { - // - // Check if this is the largest memory descriptor - // - if (MdBlock->PageCount > FreePages) - { - // - // For now, it is - // - MxFreeDescriptor = MdBlock; - } - - // - // More free pages - // - FreePages += MdBlock->PageCount; - } - } - - // - // Keep going - // - NextEntry = MdBlock->ListEntry.Flink; - } - - // - // Save original values of the free descriptor, since it'll be - // altered by early allocations - // - MxOldFreeDescriptor = *MxFreeDescriptor; - + /* Compute non paged pool limits and size */ - MiComputeNonPagedPoolVa(FreePages); - - /* Compute color information (L2 cache-separated paging lists) */ - MiComputeColorInformation(); - - // - // Calculate the number of bytes for the PFN database, double it for ARM3, - // then add the color tables and convert to pages - // - MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN); - //MxPfnAllocation <<= 1; - MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2); - MxPfnAllocation >>= PAGE_SHIFT; - - // - // We have to add one to the count here, because in the process of - // shifting down to the page size, we actually ended up getting the - // lower aligned size (so say, 0x5FFFF bytes is now 0x5F pages). - // Later on, we'll shift this number back into bytes, which would cause - // us to end up with only 0x5F000 bytes -- when we actually want to have - // 0x60000 bytes. - // - MxPfnAllocation++; + MiComputeNonPagedPoolVa(MiNumberOfFreePages);
// // Now calculate the nonpaged pool expansion VA region
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Jul 28 23:44:24 2010 @@ -441,6 +441,7 @@ extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT]; extern PMMPTE MmSharedUserDataPte; extern LIST_ENTRY MmProcessList; +extern PFN_NUMBER MiNumberOfFreePages;
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x]) #define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/mminit.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Wed Jul 28 23:44:24 2010 @@ -353,6 +353,14 @@ SIZE_T MmTotalCommitLimit; SIZE_T MmTotalCommitLimitMaximum;
+SCHAR LocationByMemoryType[LoaderMaximum]; +#define MiIsMemoryTypeInDatabase(t) (LocationByMemoryType[t] != -1) +#define MiIsMemoryTypeFree(t) (LocationByMemoryType[t] == FreePageList) + +PFN_NUMBER MiNumberOfFreePages = 0; +PFN_NUMBER MiEarlyAllocCount = 0; +ULONG MiNumberDescriptors = 0; + /* PRIVATE FUNCTIONS **********************************************************/
#ifndef _M_AMD64 @@ -379,6 +387,95 @@ } } #endif + +VOID +NTAPI +MiScanMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PLIST_ENTRY NextEntry; + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; + + /* Setup memory locations */ + LocationByMemoryType[LoaderExceptionBlock] = ActiveAndValid; + LocationByMemoryType[LoaderSystemBlock] = ActiveAndValid; + LocationByMemoryType[LoaderFree] = FreePageList; + LocationByMemoryType[LoaderBad] = BadPageList; + LocationByMemoryType[LoaderLoadedProgram] = FreePageList; + LocationByMemoryType[LoaderFirmwareTemporary] = FreePageList; + LocationByMemoryType[LoaderFirmwarePermanent] = -1; + LocationByMemoryType[LoaderOsloaderHeap] = ActiveAndValid; + LocationByMemoryType[LoaderOsloaderStack] = FreePageList; + LocationByMemoryType[LoaderSystemCode] = ActiveAndValid; + LocationByMemoryType[LoaderHalCode] = ActiveAndValid; + LocationByMemoryType[LoaderBootDriver] = ActiveAndValid; + LocationByMemoryType[LoaderConsoleInDriver] = ActiveAndValid; + LocationByMemoryType[LoaderConsoleOutDriver] = ActiveAndValid; + LocationByMemoryType[LoaderStartupDpcStack] = ActiveAndValid; + LocationByMemoryType[LoaderStartupKernelStack] = ActiveAndValid; + LocationByMemoryType[LoaderStartupPanicStack] = ActiveAndValid; + LocationByMemoryType[LoaderStartupPcrPage] = ActiveAndValid; + LocationByMemoryType[LoaderStartupPdrPage] = ActiveAndValid; + LocationByMemoryType[LoaderRegistryData] = ActiveAndValid; + LocationByMemoryType[LoaderMemoryData] = ActiveAndValid; + LocationByMemoryType[LoaderNlsData] = ActiveAndValid; + LocationByMemoryType[LoaderSpecialMemory] = -1; + LocationByMemoryType[LoaderBBTMemory] = -1; + LocationByMemoryType[LoaderReserve] = ActiveAndValid; + LocationByMemoryType[LoaderXIPRom] = ActiveAndValid; + LocationByMemoryType[LoaderHALCachedMemory] = ActiveAndValid; + LocationByMemoryType[LoaderLargePageFiller] = ActiveAndValid; + LocationByMemoryType[LoaderErrorLogMemory] = ActiveAndValid; + + /* Loop the memory descriptors */ + for (NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; + NextEntry != &LoaderBlock->MemoryDescriptorListHead; + NextEntry = NextEntry->Flink) + { + /* Count descriptor */ + MiNumberDescriptors++; + + /* Get the descriptor */ + MdBlock = CONTAINING_RECORD(NextEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + DPRINT("MD Type: %lx Base: %lx Count: %lx\n", + MdBlock->MemoryType, MdBlock->BasePage, MdBlock->PageCount); + + /* Skip memory that is not part of the database */ + if (!MiIsMemoryTypeInDatabase(MdBlock->MemoryType)) continue; + + /* Check if BURNMEM was used */ + if (MdBlock->MemoryType != LoaderBad) + { + /* Count this in the total of pages */ + MmNumberOfPhysicalPages += MdBlock->PageCount; + } + + /* Update the lowest and highest page */ + MmLowestPhysicalPage = min(MmLowestPhysicalPage, MdBlock->BasePage); + MmHighestPhysicalPage = max(MmHighestPhysicalPage, + MdBlock->BasePage + MdBlock->PageCount - 1); + + /* Check if this is free memory */ + if (MiIsMemoryTypeFree(MdBlock->MemoryType)) + { + /* Count it too free pages */ + MiNumberOfFreePages += MdBlock->PageCount; + + /* Check if this is the largest memory descriptor */ + if (MdBlock->PageCount > MiEarlyAllocCount) + { + /* Use this one for early allocations */ + MxFreeDescriptor = MdBlock; + MiEarlyAllocCount = MxFreeDescriptor->PageCount; + } + } + } + + // Save original values of the free descriptor, since it'll be + // altered by early allocations + MxOldFreeDescriptor = *MxFreeDescriptor; +}
PFN_NUMBER NTAPI @@ -1294,86 +1391,31 @@ KeLowerIrql(OldIrql); }
-PFN_NUMBER -NTAPI -MiPagesInLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock, - IN PBOOLEAN IncludeType) -{ - PLIST_ENTRY NextEntry; - PFN_NUMBER PageCount = 0; - PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; - - // - // Now loop through the descriptors - // - NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) - { - // - // Grab each one, and check if it's one we should include - // - MdBlock = CONTAINING_RECORD(NextEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - if ((MdBlock->MemoryType < LoaderMaximum) && - (IncludeType[MdBlock->MemoryType])) - { - // - // Add this to our running total - // - PageCount += MdBlock->PageCount; - } - - // - // Try the next descriptor - // - NextEntry = MdBlock->ListEntry.Flink; - } - - // - // Return the total - // - return PageCount; -} - PPHYSICAL_MEMORY_DESCRIPTOR NTAPI MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PBOOLEAN IncludeType) { PLIST_ENTRY NextEntry; - ULONG Run = 0, InitialRuns = 0; + ULONG Run = 0; PFN_NUMBER NextPage = -1, PageCount = 0; PPHYSICAL_MEMORY_DESCRIPTOR Buffer, NewBuffer; PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
// - // Scan the memory descriptors - // - NextEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - while (NextEntry != &LoaderBlock->MemoryDescriptorListHead) - { - // - // For each one, increase the memory allocation estimate - // - InitialRuns++; - NextEntry = NextEntry->Flink; - } - - // // Allocate the maximum we'll ever need // Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(PHYSICAL_MEMORY_DESCRIPTOR) + sizeof(PHYSICAL_MEMORY_RUN) * - (InitialRuns - 1), + (MiNumberDescriptors - 1), 'lMmM'); if (!Buffer) return NULL;
// // For now that's how many runs we have // - Buffer->NumberOfRuns = InitialRuns; + Buffer->NumberOfRuns = MiNumberDescriptors;
// // Now loop through the descriptors again @@ -1437,7 +1479,7 @@ // // Our guess was probably exaggerated... // - if (InitialRuns > Run) + if (MiNumberDescriptors > Run) { // // Allocate a more accurately sized buffer @@ -1686,7 +1728,6 @@ BOOLEAN IncludeType[LoaderMaximum]; PVOID Bitmap; PPHYSICAL_MEMORY_RUN Run; - PFN_NUMBER PageCount;
// // Instantiate memory that we don't consider RAM/usable @@ -1812,16 +1853,33 @@
/* Initialize the Loader Lock */ KeInitializeMutant(&MmSystemLoadLock, FALSE); - - // - // Count physical pages on the system - // - PageCount = MiPagesInLoaderBlock(LoaderBlock, IncludeType); - + + /* Scan the boot loader memory descriptors */ + MiScanMemoryDescriptors(LoaderBlock); + + /* Compute color information (L2 cache-separated paging lists) */ + MiComputeColorInformation(); + + // Calculate the number of bytes for the PFN database, double it for ARM3, + // then add the color tables and convert to pages + MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN); + //MxPfnAllocation <<= 1; + MxPfnAllocation += (MmSecondaryColors * sizeof(MMCOLOR_TABLES) * 2); + MxPfnAllocation >>= PAGE_SHIFT; + + // We have to add one to the count here, because in the process of + // shifting down to the page size, we actually ended up getting the + // lower aligned size (so say, 0x5FFFF bytes is now 0x5F pages). + // Later on, we'll shift this number back into bytes, which would cause + // us to end up with only 0x5F000 bytes -- when we actually want to have + // 0x60000 bytes. + // + MxPfnAllocation++; + // // Check if this is a machine with less than 19MB of RAM // - if (PageCount < MI_MIN_PAGES_FOR_SYSPTE_TUNING) + if (MmNumberOfPhysicalPages < MI_MIN_PAGES_FOR_SYSPTE_TUNING) { // // Use the very minimum of system PTEs @@ -1834,7 +1892,7 @@ // Use the default, but check if we have more than 32MB of RAM // MmNumberOfSystemPtes = 11000; - if (PageCount > MI_MIN_PAGES_FOR_SYSPTE_BOOST) + if (MmNumberOfPhysicalPages > MI_MIN_PAGES_FOR_SYSPTE_BOOST) // { // // Double the amount of system PTEs @@ -1858,12 +1916,12 @@ { /* Use the default value */ MmAllocationFragment = MI_ALLOCATION_FRAGMENT; - if (PageCount < ((256 * _1MB) / PAGE_SIZE)) + if (MmNumberOfPhysicalPages < ((256 * _1MB) / PAGE_SIZE)) // { /* On memory systems with less than 256MB, divide by 4 */ MmAllocationFragment = MI_ALLOCATION_FRAGMENT / 4; } - else if (PageCount < (_1GB / PAGE_SIZE)) + else if (MmNumberOfPhysicalPages < (_1GB / PAGE_SIZE)) // { /* On systems with less than 1GB, divide by 2 */ MmAllocationFragment = MI_ALLOCATION_FRAGMENT / 2;
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c [iso-8859-1] Wed Jul 28 23:44:24 2010 @@ -69,7 +69,7 @@
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor; MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor; -ULONG MiNumberDescriptors = 0; +extern ULONG MiNumberDescriptors; PFN_NUMBER MiSystemPages = 0; BOOLEAN MiIncludeType[LoaderMaximum];