[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
This commit is contained in:
Jérôme Gardou 2016-10-18 20:19:00 +00:00
parent 63bbaff803
commit 3a5149de3e
3 changed files with 58 additions and 23 deletions

View file

@ -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);
}

View file

@ -68,6 +68,8 @@ MmZeroPageThread(VOID)
NULL,
NULL);
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmZeroingPageThreadActive = TRUE;
while (TRUE)
{
if (!MmFreePageListHead.Total)

View file

@ -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