From e2d5ba4e1fff8251d3960af87be6f77e72672e7b Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Thu, 13 Mar 2008 15:26:17 +0000 Subject: [PATCH] Simplify and rename the functions that touch UserPageListHead. They were confusingly coded to accept any flavor of PFN_TYPE, which resulted in at least one bug. Constrained the calls to the MmRequest/ReleasePageMemoryConsumer and MmTrimUserMemory. svn path=/trunk/; revision=32673 --- reactos/ntoskrnl/include/internal/mm.h | 6 +++- reactos/ntoskrnl/mm/balance.c | 7 ++++- reactos/ntoskrnl/mm/freelist.c | 38 +++++++++++++------------- reactos/ntoskrnl/mm/wset.c | 3 +- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 68a9d756809..99e8c7010d7 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -1025,7 +1025,11 @@ MmGetLRUFirstUserPage(VOID); VOID NTAPI -MmSetLRULastPage(PFN_TYPE Page); +MmInsertLRULastUserPage(PFN_TYPE Page); + +VOID +NTAPI +MmRemoveLRUUserPage(PFN_TYPE Page); VOID NTAPI diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index ed8e6cd95e3..7baf62930c0 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -114,6 +114,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page) Entry = RemoveHeadList(&AllocationListHead); Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); KeReleaseSpinLock(&AllocationListLock, oldIrql); + if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); Request->Page = Page; KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); } @@ -121,6 +122,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page) else { KeReleaseSpinLock(&AllocationListLock, oldIrql); + if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); MmDereferencePage(Page); } @@ -262,7 +264,9 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, { KEBUGCHECK(NO_PAGES_AVAILABLE); } - MmSetLRULastPage(Page); + /* Update the Consumer */ + MiGetPfnEntry(Page)->Flags.Consumer = Consumer; + if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); *AllocatedPage = Page; (void)InterlockedDecrementUL(&MiPagesRequired); return(STATUS_SUCCESS); @@ -276,6 +280,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, { KEBUGCHECK(NO_PAGES_AVAILABLE); } + if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); *AllocatedPage = Page; return(STATUS_SUCCESS); diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index c0567fa21ce..ad84db26df1 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -31,8 +31,12 @@ PPHYSICAL_PAGE MmPageArray; ULONG MmPageArraySize; static KSPIN_LOCK PageListLock; +/* List of pages allocated to the MC_USER Consumer */ static LIST_ENTRY UserPageListHead; +/* List of pages zeroed by the ZPW (MmZeroPageThreadMain) */ static LIST_ENTRY FreeZeroedPageListHead; +/* List of free pages, filled by MmGetReferenceCountPage and + * and MmInitializePageList */ static LIST_ENTRY FreeUnzeroedPageListHead; static KEVENT ZeroPageThreadEvent; @@ -65,19 +69,16 @@ MmGetLRUFirstUserPage(VOID) VOID NTAPI -MmSetLRULastPage(PFN_TYPE Pfn) +MmInsertLRULastUserPage(PFN_TYPE Pfn) { KIRQL oldIrql; PPHYSICAL_PAGE Page; KeAcquireSpinLock(&PageListLock, &oldIrql); Page = MiGetPfnEntry(Pfn); - if (Page->Flags.Type == MM_PHYSICAL_PAGE_USED && - Page->Flags.Consumer == MC_USER) - { - RemoveEntryList(&Page->ListEntry); - InsertTailList(&UserPageListHead, &Page->ListEntry); - } + ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); + ASSERT(Page->Flags.Consumer == MC_USER); + InsertTailList(&UserPageListHead, &Page->ListEntry); KeReleaseSpinLock(&PageListLock, oldIrql); } @@ -92,15 +93,9 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn) KeAcquireSpinLock(&PageListLock, &oldIrql); Page = MiGetPfnEntry(PreviousPfn); - if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED || - Page->Flags.Consumer != MC_USER) - { - NextListEntry = UserPageListHead.Flink; - } - else - { - NextListEntry = Page->ListEntry.Flink; - } + ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); + ASSERT(Page->Flags.Consumer == MC_USER); + NextListEntry = Page->ListEntry.Flink; if (NextListEntry == &UserPageListHead) { KeReleaseSpinLock(&PageListLock, oldIrql); @@ -111,6 +106,13 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn) return PageDescriptor - MmPageArray; } +VOID +NTAPI +MmRemoveLRUUserPage(PFN_TYPE Page) +{ + RemoveEntryList(&MiGetPfnEntry(Page)->ListEntry); +} + PFN_TYPE NTAPI MmGetContinuousPages(ULONG NumberOfBytes, @@ -782,7 +784,6 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry) KeReleaseSpinLock(&PageListLock, oldIrql); PfnOffset = PageDescriptor - MmPageArray; - MmSetLRULastPage(PfnOffset); if (NeedClear) { MiZeroPage(PfnOffset); @@ -882,7 +883,7 @@ MmAllocPagesSpecifyRange(ULONG Consumer, /* Remember the page */ pfn = PageDescriptor - MmPageArray; Pages[NumberOfPagesFound++] = pfn; - MmSetLRULastPage(pfn); + if(Consumer == MC_USER) MmInsertLRULastUserPage(pfn); } } else @@ -917,7 +918,6 @@ MmAllocPagesSpecifyRange(ULONG Consumer, /* Remember the page */ Pages[NumberOfPagesFound++] = pfn; - MmSetLRULastPage(pfn); if (NumberOfPagesFound == NumberOfPages) break; } diff --git a/reactos/ntoskrnl/mm/wset.c b/reactos/ntoskrnl/mm/wset.c index 45d78b99314..df570353d6c 100644 --- a/reactos/ntoskrnl/mm/wset.c +++ b/reactos/ntoskrnl/mm/wset.c @@ -38,7 +38,8 @@ MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages) } else if (Status == STATUS_PAGEFILE_QUOTA) { - MmSetLRULastPage(CurrentPage); + MmRemoveLRUUserPage(CurrentPage); + MmInsertLRULastUserPage(CurrentPage); } CurrentPage = NextPage;