[NTOSKRNL]

- Tweak the balancer to prevent an excessive buildup of user pages while cache is paged out completely each run
- Bugcheck if we've trimmed everything as much as possibly but we are still in need of pages

svn path=/trunk/; revision=54771
This commit is contained in:
Cameron Gutman 2011-12-28 01:18:35 +00:00
parent f8e647e8a2
commit 4cf336fa2a

View file

@ -132,17 +132,20 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
VOID ULONG
NTAPI NTAPI
MiTrimMemoryConsumer(ULONG Consumer) MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
{ {
LONG Target = 0; LONG Target = InitialTarget;
ULONG NrFreedPages = 0; ULONG NrFreedPages = 0;
NTSTATUS Status; NTSTATUS Status;
/* Make sure we can trim this consumer */ /* Make sure we can trim this consumer */
if (!MiMemoryConsumers[Consumer].Trim) if (!MiMemoryConsumers[Consumer].Trim)
return; {
/* Return the unmodified initial target */
return InitialTarget;
}
if (MiMemoryConsumers[Consumer].PagesUsed > MiMemoryConsumers[Consumer].PagesTarget) if (MiMemoryConsumers[Consumer].PagesUsed > MiMemoryConsumers[Consumer].PagesTarget)
{ {
@ -157,8 +160,12 @@ MiTrimMemoryConsumer(ULONG Consumer)
if (Target) if (Target)
{ {
/* Swap at least MiMinimumPagesPerRun */ if (!InitialTarget)
{
/* If there was no initial target,
* swap at least MiMinimumPagesPerRun */
Target = max(Target, MiMinimumPagesPerRun); Target = max(Target, MiMinimumPagesPerRun);
}
/* Now swap the pages out */ /* Now swap the pages out */
Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages); Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
@ -169,6 +176,20 @@ MiTrimMemoryConsumer(ULONG Consumer)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
/* Update the target */
if (NrFreedPages < Target)
Target -= NrFreedPages;
else
Target = 0;
/* Return the remaining pages needed to meet the target */
return Target;
}
else
{
/* Initial target is zero and we don't have anything else to add */
return 0;
} }
} }
@ -348,16 +369,26 @@ MiBalancerThread(PVOID Unused)
if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1) if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
{ {
ULONG InitialTarget = 0;
do
{
ULONG OldTarget = InitialTarget;
/* Trim each consumer */
for (i = 0; i < MC_MAXIMUM; i++) for (i = 0; i < MC_MAXIMUM; i++)
{ {
MiTrimMemoryConsumer(i); InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
} }
if (MmAvailablePages < MiMinimumAvailablePages) /* No pages left to swap! */
if (InitialTarget != 0 &&
InitialTarget == OldTarget)
{ {
/* This is really bad... */ /* Game over */
DPRINT1("Balancer failed to resolve low memory condition! Complete memory exhaustion is imminent!\n"); KeBugCheck(NO_PAGES_AVAILABLE);
} }
} while (InitialTarget != 0);
} }
else else
{ {