From: Sir Richard Date: Thu, 11 Feb 2010 18:44:28 +0000 (+0000) Subject: [NTOS]: Remove many hacks in freelist.c regarding the differences between PHYSICAL_PA... X-Git-Tag: backups/jcatena-branch@60647^2~9 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7872be60713d576fd552607fd4f96822c177c926 [NTOS]: Remove many hacks in freelist.c regarding the differences between PHYSICAL_PAGE and MMPFN. ReferenceCount field is now accessed directly. LockCount is gone. Type is gone: if a page is used, it has a consumer and is in the ActiveAndValid state, if it's free, it's on the free or zero page list. Get rid of Zero, if a page is zeroed, it is on the zero page list. [NTOS]: These changes will allow a smoother migration to MMPFN later on. svn path=/trunk/; revision=45577 --- diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index 9f6192bedf2..eae79ccf8ab 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -232,6 +232,8 @@ MiIsBalancerThread(VOID) PsGetCurrentThread() == MiBalancerThreadId.UniqueThread; } +VOID NTAPI MiSetConsumer(IN PFN_TYPE Pfn, IN ULONG Consumer); + NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, @@ -316,8 +318,8 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, { KeBugCheck(NO_PAGES_AVAILABLE); } - /* Update the Consumer */ - MiGetPfnEntry(Page)->u3.e1.PageLocation = Consumer; + /* Update the Consumer and make the page active */ + MiSetConsumer(Page, Consumer); if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); *AllocatedPage = Page; (void)InterlockedDecrementUL(&MiPagesRequired); diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index e32dcb2d1f1..c13b8b21693 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -21,11 +21,6 @@ #define MODULE_INVOLVED_IN_ARM3 #include "ARM3/miarm.h" -/* TYPES *******************************************************************/ - -#define MM_PHYSICAL_PAGE_FREE (0x1) -#define MM_PHYSICAL_PAGE_USED (0x2) - /* GLOBALS ****************************************************************/ // @@ -34,14 +29,9 @@ // // REACTOS NT // -#define Consumer PageLocation -#define Type CacheAttribute -#define Zero PrototypePte -#define LockCount u3.e1.PageColor +#define Consumer u3.e1.PageColor #define RmapListHead AweReferenceCount #define SavedSwapEntry u4.EntireFrame -#define Flags u3.e1 -#define ReferenceCount u3.ReferenceCount #define RemoveEntryList(x) RemoveEntryList((PLIST_ENTRY)x) #define InsertTailList(x, y) InsertTailList(x, (PLIST_ENTRY)y) #define ListEntry u1 @@ -100,7 +90,6 @@ MmGetLRUFirstUserPage(VOID) return 0; } PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); - ASSERT_PFN(PageDescriptor); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return PageDescriptor - MmPfnDatabase[0]; } @@ -114,9 +103,9 @@ MmInsertLRULastUserPage(PFN_TYPE Pfn) oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(Pfn); - ASSERT(Page); - ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); - ASSERT(Page->Flags.Consumer == MC_USER); +// if (!Page->Consumer != MC_USER) DPRINT1("Page Consumer: %d\n", Page->Consumer); + ASSERT(Page->Consumer == MC_USER); + ASSERT(Page->u3.e1.PageLocation = ActiveAndValid); InsertTailList(&UserPageListHead, &Page->ListEntry); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); } @@ -132,9 +121,8 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn) oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(PreviousPfn); - ASSERT(Page); - ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); - ASSERT(Page->Flags.Consumer == MC_USER); + ASSERT(Page->Consumer == MC_USER); + ASSERT(Page->u3.e1.PageLocation = ActiveAndValid); NextListEntry = (PLIST_ENTRY)Page->ListEntry.Flink; if (NextListEntry == &UserPageListHead) { @@ -153,6 +141,14 @@ MmRemoveLRUUserPage(PFN_TYPE Page) RemoveEntryList(&MiGetPfnEntry(Page)->ListEntry); } +BOOLEAN +NTAPI +MiIsPfnInUse(IN PMMPFN Pfn1) +{ + return ((Pfn1->u3.e1.PageLocation != FreePageList) && + (Pfn1->u3.e1.PageLocation != ZeroedPageList)); +} + PFN_NUMBER NTAPI MiFindContiguousPages(IN PFN_NUMBER LowestPfn, @@ -209,7 +205,7 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn, // // If this PFN is in use, ignore it // - if (Pfn1->Flags.Type != MM_PHYSICAL_PAGE_FREE) continue; + if (MiIsPfnInUse(Pfn1)) continue; // // If we haven't chosen a start PFN yet and the caller specified an @@ -244,7 +240,7 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn, // // Things might've changed for us. Is the page still free? // - if (Pfn1->Flags.Type != MM_PHYSICAL_PAGE_FREE) break; + if (MiIsPfnInUse(Pfn1)) break; // // So far so good. Is this the last confirmed valid page? @@ -265,7 +261,7 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn, // // If this was an unzeroed page, there are now less // - if (Pfn1->Flags.Zero == 0) UnzeroedPageCount--; + if (Pfn1->u3.e1.PageLocation == ZeroedPageList) UnzeroedPageCount--; // // One less free page @@ -276,22 +272,25 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn, // This PFN is now a used page, set it up // RemoveEntryList(&Pfn1->ListEntry); - Pfn1->Flags.Type = MM_PHYSICAL_PAGE_USED; - Pfn1->Flags.Consumer = MC_NPPOOL; - Pfn1->ReferenceCount = 1; - Pfn1->LockCount = 0; + Pfn1->Consumer = MC_NPPOOL; + Pfn1->u3.e2.ReferenceCount = 1; Pfn1->SavedSwapEntry = 0; // // Check if it was already zeroed // - if (Pfn1->Flags.Zero == 0) + if (Pfn1->u3.e1.PageLocation != ZeroedPageList) { // // It wasn't, so zero it // MiZeroPage(MiGetPfnEntryIndex(Pfn1)); } + + // + // Mark it in use + // + Pfn1->u3.e1.PageLocation = ActiveAndValid; // // Check if this is the last PFN, otherwise go on @@ -303,8 +302,8 @@ MiFindContiguousPages(IN PFN_NUMBER LowestPfn, // // Mark the first and last PFN so we can find them later // - Pfn1->Flags.StartOfAllocation = 1; - (Pfn1 + SizeInPages - 1)->Flags.EndOfAllocation = 1; + Pfn1->u3.e1.StartOfAllocation = 1; + (Pfn1 + SizeInPages - 1)->u3.e1.EndOfAllocation = 1; // // Now it's safe to let go of the PFN lock @@ -466,18 +465,17 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // // Make sure it's really free // - ASSERT(Pfn1->Flags.Type == MM_PHYSICAL_PAGE_FREE); - ASSERT(Pfn1->ReferenceCount == 0); + ASSERT(MiIsPfnInUse(Pfn1) == FALSE); + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); // // Allocate it and mark it // - Pfn1->Flags.Type = MM_PHYSICAL_PAGE_USED; - Pfn1->Flags.Consumer = MC_NPPOOL; - Pfn1->Flags.StartOfAllocation = 1; - Pfn1->Flags.EndOfAllocation = 1; - Pfn1->ReferenceCount = 1; - Pfn1->LockCount = 0; + Pfn1->Consumer = MC_NPPOOL; + Pfn1->u3.e1.StartOfAllocation = 1; + Pfn1->u3.e1.EndOfAllocation = 1; + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; Pfn1->SavedSwapEntry = 0; // @@ -513,29 +511,27 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // // Make sure it's free and if this is our first pass, zeroed // - if (Pfn1->Flags.Type != MM_PHYSICAL_PAGE_FREE) continue; - if (Pfn1->Flags.Zero != LookForZeroedPages) continue; + if (!MiIsPfnInUse(Pfn1)) continue; + if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) != LookForZeroedPages) continue; // // Sanity checks // - ASSERT(Pfn1->ReferenceCount == 0); + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); // // Now setup the page and mark it // - Pfn1->Flags.Type = MM_PHYSICAL_PAGE_USED; - Pfn1->Flags.Consumer = MC_NPPOOL; - Pfn1->ReferenceCount = 1; - Pfn1->Flags.StartOfAllocation = 1; - Pfn1->Flags.EndOfAllocation = 1; - Pfn1->LockCount = 0; + Pfn1->Consumer = MC_NPPOOL; + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u3.e1.StartOfAllocation = 1; + Pfn1->u3.e1.EndOfAllocation = 1; Pfn1->SavedSwapEntry = 0; // // If this page was unzeroed, we've consumed such a page // - if (!Pfn1->Flags.Zero) UnzeroedPageCount--; + if (Pfn1->u3.e1.PageLocation != ZeroedPageList) UnzeroedPageCount--; // // Decrease available pages @@ -603,7 +599,8 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // Pfn1 = MiGetPfnEntry(Page); ASSERT(Pfn1); - if (Pfn1->Flags.Zero == 0) MiZeroPage(Page); + if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPage(Page); + Pfn1->u3.e1.PageLocation = ActiveAndValid; } // @@ -620,7 +617,7 @@ MmDumpPfnDatabase(VOID) { ULONG i; PPHYSICAL_PAGE Pfn1; - PCHAR State = "????", Consumer = "Unknown"; + PCHAR State = "????", Type = "Unknown"; KIRQL OldIrql; ULONG Totals[5] = {0}, FreePages = 0; @@ -637,67 +634,63 @@ MmDumpPfnDatabase(VOID) // // Get the consumer // - switch (Pfn1->Flags.Consumer) + switch (Pfn1->Consumer) { case MC_NPPOOL: - Consumer = "Nonpaged Pool"; + Type = "Nonpaged Pool"; break; case MC_PPOOL: - Consumer = "Paged Pool"; + Type = "Paged Pool"; break; case MC_CACHE: - Consumer = "File System Cache"; + Type = "File System Cache"; break; case MC_USER: - Consumer = "Process Working Set"; + Type = "Process Working Set"; break; case MC_SYSTEM: - Consumer = "System"; + Type = "System"; break; } // // Get the type // - switch (Pfn1->Flags.Type) + if (MiIsPfnInUse(Pfn1)) { - case MM_PHYSICAL_PAGE_USED: - - State = "Used"; - Totals[Pfn1->Flags.Consumer]++; - break; - - case MM_PHYSICAL_PAGE_FREE: - - State = "Free"; - Consumer = "Free"; - FreePages++; - break; + State = "Used"; + Totals[Pfn1->Consumer]++; } - + else + { + State = "Free"; + Type = "Free"; + FreePages++; + break; + } + // // Pretty-print the page // - DbgPrint("0x%08p:\t%04s\t%20s\t(%02d.%02d) [%08p])\n", + DbgPrint("0x%08p:\t%04s\t%20s\t(%02d) [%08p])\n", i << PAGE_SHIFT, State, - Consumer, - Pfn1->ReferenceCount, - Pfn1->LockCount, + Type, + Pfn1->u3.e2.ReferenceCount, Pfn1->RmapListHead); } DbgPrint("Nonpaged Pool: %d pages\t[%d KB]\n", Totals[MC_NPPOOL], (Totals[MC_NPPOOL] << PAGE_SHIFT) / 1024); - DbgPrint("Paged Pool: %d pages\t[%d KB]\n", Totals[MC_PPOOL], (Totals[MC_PPOOL] << PAGE_SHIFT) / 1024); + DbgPrint("Paged Pool: %d pages\t[%d KB]\n", Totals[MC_PPOOL], (Totals[MC_PPOOL] << PAGE_SHIFT) / 1024); DbgPrint("File System Cache: %d pages\t[%d KB]\n", Totals[MC_CACHE], (Totals[MC_CACHE] << PAGE_SHIFT) / 1024); DbgPrint("Process Working Set: %d pages\t[%d KB]\n", Totals[MC_USER], (Totals[MC_USER] << PAGE_SHIFT) / 1024); DbgPrint("System: %d pages\t[%d KB]\n", Totals[MC_SYSTEM], (Totals[MC_SYSTEM] << PAGE_SHIFT) / 1024); @@ -723,9 +716,9 @@ MmInitializePageList(VOID) /* This is what a used page looks like */ RtlZeroMemory(&UsedPage, sizeof(UsedPage)); - UsedPage.Flags.Type = MM_PHYSICAL_PAGE_USED; - UsedPage.Flags.Consumer = MC_NPPOOL; - UsedPage.ReferenceCount = 1; + UsedPage.Consumer = MC_NPPOOL; + UsedPage.u3.e1.PageLocation = ActiveAndValid; + UsedPage.u3.e2.ReferenceCount = 1; /* Loop the memory descriptors */ for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink; @@ -759,7 +752,7 @@ MmInitializePageList(VOID) for (i = 0; i < Md->PageCount; i++) { /* Mark it as a free page */ - MmPfnDatabase[0][Md->BasePage + i].Flags.Type = MM_PHYSICAL_PAGE_FREE; + MmPfnDatabase[0][Md->BasePage + i].u3.e1.PageLocation = FreePageList; InsertTailList(&FreeUnzeroedPageListHead, &MmPfnDatabase[0][Md->BasePage + i].ListEntry); UnzeroedPageCount++; @@ -782,7 +775,7 @@ MmInitializePageList(VOID) for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++) { /* Ensure this page was not added previously */ - ASSERT(MmPfnDatabase[0][i].Flags.Type == 0); + ASSERT(MmPfnDatabase[0][i].Consumer == 0); /* Mark it as used kernel memory */ MmPfnDatabase[0][i] = UsedPage; @@ -859,13 +852,8 @@ MmReferencePage(PFN_TYPE Pfn) Page = MiGetPfnEntry(Pfn); ASSERT(Page); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Referencing non-used page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - Page->ReferenceCount++; + Page->u3.e2.ReferenceCount++; } ULONG @@ -881,13 +869,8 @@ MmGetReferenceCountPage(PFN_TYPE Pfn) oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(Pfn); ASSERT(Page); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Getting reference count for free page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - RCount = Page->ReferenceCount; + RCount = Page->u3.e2.ReferenceCount; KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return(RCount); @@ -897,10 +880,16 @@ BOOLEAN NTAPI MmIsPageInUse(PFN_TYPE Pfn) { + return MiIsPfnInUse(MiGetPfnEntry(Pfn)); +} - DPRINT("MmIsPageInUse(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - - return (MiGetPfnEntry(Pfn)->Flags.Type == MM_PHYSICAL_PAGE_USED); +VOID +NTAPI +MiSetConsumer(IN PFN_TYPE Pfn, + IN ULONG Type) +{ + MiGetPfnEntry(Pfn)->Consumer = Type; + MiGetPfnEntry(Pfn)->u3.e1.PageLocation = ActiveAndValid; } VOID @@ -914,45 +903,12 @@ MmDereferencePage(PFN_TYPE Pfn) Page = MiGetPfnEntry(Pfn); ASSERT(Page); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Dereferencing free page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (Page->ReferenceCount == 0) - { - DPRINT1("Derefrencing page with reference count 0\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - - Page->ReferenceCount--; - if (Page->ReferenceCount == 0) + Page->u3.e2.ReferenceCount--; + if (Page->u3.e2.ReferenceCount == 0) { MmAvailablePages++; - if (Page->Flags.Consumer == MC_USER) RemoveEntryList(&Page->ListEntry); - if (Page->RmapListHead != (LONG)NULL) - { - DPRINT1("Freeing page with rmap entries.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (Page->LockCount > 0) - { - DPRINT1("Freeing locked page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (Page->SavedSwapEntry != 0) - { - DPRINT1("Freeing page with swap entry.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Freeing page with flags %x\n", - Page->Flags.Type); - KeBugCheck(MEMORY_MANAGEMENT); - } - Page->Flags.Type = MM_PHYSICAL_PAGE_FREE; - Page->Flags.Consumer = MC_MAXIMUM; + if (Page->Consumer == MC_USER) RemoveEntryList(&Page->ListEntry); + Page->u3.e1.PageLocation = FreePageList; InsertTailList(&FreeUnzeroedPageListHead, &Page->ListEntry); UnzeroedPageCount++; @@ -963,73 +919,9 @@ MmDereferencePage(PFN_TYPE Pfn) } } -ULONG -NTAPI -MmGetLockCountPage(PFN_TYPE Pfn) -{ - KIRQL oldIrql; - ULONG CurrentLockCount; - PPHYSICAL_PAGE Page; - - DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - - oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - - Page = MiGetPfnEntry(Pfn); - ASSERT(Page); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Getting lock count for free page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - - CurrentLockCount = Page->LockCount; - KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); - - return(CurrentLockCount); -} - -VOID -NTAPI -MmLockPage(PFN_TYPE Pfn) -{ - PPHYSICAL_PAGE Page; - - DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - - Page = MiGetPfnEntry(Pfn); - ASSERT(Page); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Locking free page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - - Page->LockCount++; -} - -VOID -NTAPI -MmUnlockPage(PFN_TYPE Pfn) -{ - PPHYSICAL_PAGE Page; - - DPRINT("MmUnlockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - - Page = MiGetPfnEntry(Pfn); - ASSERT(Page); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DPRINT1("Unlocking free page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - - Page->LockCount--; -} - PFN_TYPE NTAPI -MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry) +MmAllocPage(ULONG Type, SWAPENTRY SwapEntry) { PFN_TYPE PfnOffset; PLIST_ENTRY ListEntry; @@ -1065,29 +957,19 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry) PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); } - if (PageDescriptor->Flags.Type != MM_PHYSICAL_PAGE_FREE) - { - DPRINT1("Got non-free page from freelist\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (PageDescriptor->ReferenceCount != 0) - { - DPRINT1("%d\n", PageDescriptor->ReferenceCount); - KeBugCheck(MEMORY_MANAGEMENT); - } - PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; - PageDescriptor->Flags.Consumer = Consumer; - PageDescriptor->ReferenceCount = 1; - PageDescriptor->LockCount = 0; + PageDescriptor->Consumer = Type; + PageDescriptor->u3.e2.ReferenceCount = 1; PageDescriptor->SavedSwapEntry = SwapEntry; MmAvailablePages--; PfnOffset = PageDescriptor - MmPfnDatabase[0]; - if ((NeedClear) && (Consumer != MC_SYSTEM)) + if ((NeedClear) && (Type != MC_SYSTEM)) { MiZeroPage(PfnOffset); } + + PageDescriptor->u3.e1.PageLocation = ActiveAndValid; return PfnOffset; } @@ -1135,11 +1017,6 @@ MmZeroPageThreadMain(PVOID Ignored) KernelMode, FALSE, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ZeroPageThread: Wait failed\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } if (ZeroPageThreadShouldTerminate) { @@ -1154,14 +1031,12 @@ MmZeroPageThreadMain(PVOID Ignored) UnzeroedPageCount--; PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ - PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); Pfn = PageDescriptor - MmPfnDatabase[0]; Status = MiZeroPage(Pfn); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - PageDescriptor->Flags.Zero = 1; - PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE; + PageDescriptor->u3.e1.PageLocation = ZeroedPageList; if (NT_SUCCESS(Status)) { InsertHeadList(&FreeZeroedPageListHead, ListEntry);