[NTOS]: One last fix to the zero page thread before we move to ARM3: use MiRemoveAnyPage instead of dangerous MiRemoveHeadList. The code works on the assumption (validated by Windows through a bug check) that MiRemoveAnyPage always returns the first free page, and we also manually grab the first free page, and compare this is true. Nice way to detect PFN database corruption.

[NTOS]: Fix MiInsertZeroAtBack to increment the MmAvailablePage count, since MiRemoveAnyPage decrements it (MiRemoveHeadList did not).

svn path=/trunk/; revision=48918
This commit is contained in:
Sir Richard 2010-09-28 14:29:37 +00:00
parent 66ff3d5774
commit 354ad6b9eb
2 changed files with 27 additions and 18 deletions

View file

@ -156,8 +156,8 @@ MiInsertZeroListAtBack(IN PFN_NUMBER EntryIndex)
/* Update the page location */
Pfn1->u3.e1.PageLocation = ZeroedPageList;
/* FIXME: NOT YET Due to caller semantics: Update the available page count */
//MmAvailablePages++;
/* Update the available page count */
MmAvailablePages++;
/* Check if we've reached the configured low memory threshold */
if (MmAvailablePages == MmLowMemoryThreshold)

View file

@ -631,8 +631,8 @@ MmZeroPageThreadMain(PVOID Ignored)
{
NTSTATUS Status;
KIRQL oldIrql;
PPHYSICAL_PAGE PageDescriptor;
PFN_NUMBER Pfn;
PMMPFN Pfn1;
PFN_NUMBER PageIndex, FreePage;
ULONG Count;
PVOID ZeroAddress;
@ -660,21 +660,30 @@ MmZeroPageThreadMain(PVOID Ignored)
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
while (MmFreePageListHead.Total)
{
PageDescriptor = MiRemoveHeadList(&MmFreePageListHead);
Pfn = MiGetPfnEntryIndex(PageDescriptor);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
PageDescriptor->u1.Flink = LIST_HEAD;
ZeroAddress = MiMapPagesToZeroInHyperSpace(PageDescriptor, 1);
ASSERT(ZeroAddress);
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
PageIndex = MmFreePageListHead.Flink;
Pfn1 = MiGetPfnEntry(PageIndex);
FreePage = MiRemoveAnyPage(0); // FIXME: Use real color
if (FreePage != PageIndex)
{
KeBugCheckEx(PFN_LIST_CORRUPT,
0x8F,
FreePage,
PageIndex,
0);
}
Pfn1->u1.Flink = LIST_HEAD;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
ASSERT(ZeroAddress);
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiInsertZeroListAtBack(Pfn);
Count++;
MiInsertZeroListAtBack(PageIndex);
Count++;
}
DPRINT("Zeroed %d pages.\n", Count);
KeResetEvent(&ZeroPageThreadEvent);