From 3a5149de3ee67e4b8f7b7ee383917dac12db97cf Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Tue, 18 Oct 2016 20:19:00 +0000 Subject: [PATCH] [NTOS/MM] - Let the zero page thread decide itself whether it is active or not. - Raise the low memory limit for our good old balancer - Allow the balancer thread to wait for a page to be freed, with a lower limit than for "regular" page faults - Let ARM3 notify RosMm when a page gets freed CORE-12047 #comment Whole patch got in in r72988, 72989 and 72990 svn path=/trunk/; revision=72990 --- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 12 +++++- reactos/ntoskrnl/mm/ARM3/zeropage.c | 2 + reactos/ntoskrnl/mm/balance.c | 67 ++++++++++++++++++++--------- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index 6977f0e7fc8..8fc607c794b 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -64,7 +64,6 @@ ULONG MI_PFN_CURRENT_USAGE; CHAR MI_PFN_CURRENT_PROCESS_NAME[16] = "None yet"; /* FUNCTIONS ******************************************************************/ - static VOID MiIncrementAvailablePages( @@ -597,6 +596,9 @@ MiRemoveZeroPage(IN ULONG Color) return PageIndex; } +/* HACK for keeping legacy Mm alive */ +extern BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER PageFrameIndex); + VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) @@ -624,6 +626,13 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) ASSERT(Pfn1->u4.VerifierAllocation == 0); ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + /* HACK HACK HACK : Feed the page to legacy Mm */ + if (MmRosNotifyAvailablePage(PageFrameIndex)) + { + DPRINT1("Legacy Mm eating ARM3 page!.\n"); + return; + } + /* Get the free page list and increment its count */ ListHead = &MmFreePageListHead; ASSERT_LIST_INVARIANT(ListHead); @@ -695,7 +704,6 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex) if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive)) { /* Set the event */ - MmZeroingPageThreadActive = TRUE; KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE); } diff --git a/reactos/ntoskrnl/mm/ARM3/zeropage.c b/reactos/ntoskrnl/mm/ARM3/zeropage.c index 1715a93ae4c..4b0b9cbe649 100644 --- a/reactos/ntoskrnl/mm/ARM3/zeropage.c +++ b/reactos/ntoskrnl/mm/ARM3/zeropage.c @@ -68,6 +68,8 @@ MmZeroPageThread(VOID) NULL, NULL); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + MmZeroingPageThreadActive = TRUE; + while (TRUE) { if (!MmFreePageListHead.Total) diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index a82906b0cec..e4b108aa072 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -59,7 +59,7 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages) MiNrTotalPages = NrAvailablePages; /* Set up targets. */ - MiMinimumAvailablePages = 128; + MiMinimumAvailablePages = 256; MiMinimumPagesPerRun = 256; if ((NrAvailablePages + NrSystemPages) >= 8192) { @@ -96,9 +96,6 @@ NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page) { - PMM_ALLOCATION_REQUEST Request; - PLIST_ENTRY Entry; - if (Page == 0) { DPRINT1("Tried to release page zero.\n"); @@ -109,23 +106,10 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page) { if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); - if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL) - { - MmDereferencePage(Page); - } - else - { - Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); - MiZeroPhysicalPage(Page); - Request->Page = Page; - KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); - } - } - else - { - MmDereferencePage(Page); } + MmDereferencePage(Page); + return(STATUS_SUCCESS); } @@ -261,7 +245,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Allocate always memory for the non paged pool and for the pager thread. */ - if ((Consumer == MC_SYSTEM) || MiIsBalancerThread()) + if ((Consumer == MC_SYSTEM) /* || MiIsBalancerThread() */) { Page = MmAllocPage(Consumer); if (Page == 0) @@ -278,7 +262,8 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Make sure we don't exceed global targets. */ - if (MmAvailablePages < MiMinimumAvailablePages) + if (((MmAvailablePages < MiMinimumAvailablePages) && !MiIsBalancerThread()) + || (MmAvailablePages < (MiMinimumAvailablePages / 2))) { MM_ALLOCATION_REQUEST Request; @@ -418,6 +403,46 @@ MiBalancerThread(PVOID Unused) } } +BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER Page) +{ + PLIST_ENTRY Entry; + PMM_ALLOCATION_REQUEST Request; + PMMPFN Pfn1; + + /* Make sure the PFN lock is held */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + + if (!MiMinimumAvailablePages) + { + /* Dirty way to know if we were initialized. */ + return FALSE; + } + + Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock); + if (!Entry) + return FALSE; + + Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); + MiZeroPhysicalPage(Page); + Request->Page = Page; + + Pfn1 = MiGetPfnEntry(Page); + ASSERT(Pfn1->u3.e2.ReferenceCount == 0); + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; + + /* This marks the PFN as a ReactOS PFN */ + Pfn1->u4.AweAllocation = TRUE; + + /* Allocate the extra ReactOS Data and zero it out */ + Pfn1->u1.SwapEntry = 0; + Pfn1->RmapListHead = NULL; + + KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); + + return TRUE; +} + VOID INIT_FUNCTION NTAPI -- 2.17.1