[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)
Target = max(Target, MiMinimumPagesPerRun); {
/* If there was no initial target,
* swap at least 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)
{ {
for (i = 0; i < MC_MAXIMUM; i++) ULONG InitialTarget = 0;
{
MiTrimMemoryConsumer(i);
}
if (MmAvailablePages < MiMinimumAvailablePages) do
{ {
/* This is really bad... */ ULONG OldTarget = InitialTarget;
DPRINT1("Balancer failed to resolve low memory condition! Complete memory exhaustion is imminent!\n");
} /* Trim each consumer */
for (i = 0; i < MC_MAXIMUM; i++)
{
InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
}
/* No pages left to swap! */
if (InitialTarget != 0 &&
InitialTarget == OldTarget)
{
/* Game over */
KeBugCheck(NO_PAGES_AVAILABLE);
}
} while (InitialTarget != 0);
} }
else else
{ {