Author: sir_richard
Date: Thu Feb 11 19:44:28 2010
New Revision: 45577
URL:
http://svn.reactos.org/svn/reactos?rev=45577&view=rev
Log:
[NTOS]: Remove many hacks in freelist.c regarding the differences between PHYSICAL_PAGE
and MMPFN. ReferenceCount field is now accessed directly. LockCount is gone. Type is gone:
if a page is used, it has a consumer and is in the ActiveAndValid state, if it's free,
it's on the free or zero page list. Get rid of Zero, if a page is zeroed, it is on the
zero page list.
[NTOS]: These changes will allow a smoother migration to MMPFN later on.
Modified:
trunk/reactos/ntoskrnl/mm/balance.c
trunk/reactos/ntoskrnl/mm/freelist.c
Modified: trunk/reactos/ntoskrnl/mm/balance.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/balance.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/balance.c [iso-8859-1] Thu Feb 11 19:44:28 2010
@@ -232,6 +232,8 @@
PsGetCurrentThread() == MiBalancerThreadId.UniqueThread;
}
+VOID NTAPI MiSetConsumer(IN PFN_TYPE Pfn, IN ULONG Consumer);
+
NTSTATUS
NTAPI
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
@@ -316,8 +318,8 @@
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
- /* Update the Consumer */
- MiGetPfnEntry(Page)->u3.e1.PageLocation = Consumer;
+ /* Update the Consumer and make the page active */
+ MiSetConsumer(Page, Consumer);
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
(void)InterlockedDecrementUL(&MiPagesRequired);
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Thu Feb 11 19:44:28 2010
@@ -21,11 +21,6 @@
#define MODULE_INVOLVED_IN_ARM3
#include "ARM3/miarm.h"
-/* TYPES *******************************************************************/
-
-#define MM_PHYSICAL_PAGE_FREE (0x1)
-#define MM_PHYSICAL_PAGE_USED (0x2)
-
/* GLOBALS ****************************************************************/
//
@@ -34,14 +29,9 @@
//
// REACTOS NT
//
-#define Consumer PageLocation
-#define Type CacheAttribute
-#define Zero PrototypePte
-#define LockCount u3.e1.PageColor
+#define Consumer u3.e1.PageColor
#define RmapListHead AweReferenceCount
#define SavedSwapEntry u4.EntireFrame
-#define Flags u3.e1
-#define ReferenceCount u3.ReferenceCount
#define RemoveEntryList(x) RemoveEntryList((PLIST_ENTRY)x)
#define InsertTailList(x, y) InsertTailList(x, (PLIST_ENTRY)y)
#define ListEntry u1
@@ -100,7 +90,6 @@
return 0;
}
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
- ASSERT_PFN(PageDescriptor);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return PageDescriptor - MmPfnDatabase[0];
}
@@ -114,9 +103,9 @@
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED);
- ASSERT(Page->Flags.Consumer == MC_USER);
+// if (!Page->Consumer != MC_USER) DPRINT1("Page Consumer: %d\n",
Page->Consumer);
+ ASSERT(Page->Consumer == MC_USER);
+ ASSERT(Page->u3.e1.PageLocation = ActiveAndValid);
InsertTailList(&UserPageListHead, &Page->ListEntry);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
@@ -132,9 +121,8 @@
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(PreviousPfn);
- ASSERT(Page);
- ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED);
- ASSERT(Page->Flags.Consumer == MC_USER);
+ ASSERT(Page->Consumer == MC_USER);
+ ASSERT(Page->u3.e1.PageLocation = ActiveAndValid);
NextListEntry = (PLIST_ENTRY)Page->ListEntry.Flink;
if (NextListEntry == &UserPageListHead)
{
@@ -153,6 +141,14 @@
RemoveEntryList(&MiGetPfnEntry(Page)->ListEntry);
}
+BOOLEAN
+NTAPI
+MiIsPfnInUse(IN PMMPFN Pfn1)
+{
+ return ((Pfn1->u3.e1.PageLocation != FreePageList) &&
+ (Pfn1->u3.e1.PageLocation != ZeroedPageList));
+}
+
PFN_NUMBER
NTAPI
MiFindContiguousPages(IN PFN_NUMBER LowestPfn,
@@ -209,7 +205,7 @@
//
// If this PFN is in use, ignore it
//
- if (Pfn1->Flags.Type != MM_PHYSICAL_PAGE_FREE) continue;
+ if (MiIsPfnInUse(Pfn1)) continue;
//
// If we haven't chosen a start PFN yet and the caller specified an
@@ -244,7 +240,7 @@
//
// Things might've changed for us. Is the page still free?
//
- if (Pfn1->Flags.Type != MM_PHYSICAL_PAGE_FREE) break;
+ if (MiIsPfnInUse(Pfn1)) break;
//
// So far so good. Is this the last confirmed valid page?
@@ -265,7 +261,7 @@
//
// If this was an unzeroed page, there are now less
//
- if (Pfn1->Flags.Zero == 0) UnzeroedPageCount--;
+ if (Pfn1->u3.e1.PageLocation == ZeroedPageList)
UnzeroedPageCount--;
//
// One less free page
@@ -276,22 +272,25 @@
// This PFN is now a used page, set it up
//
RemoveEntryList(&Pfn1->ListEntry);
- Pfn1->Flags.Type = MM_PHYSICAL_PAGE_USED;
- Pfn1->Flags.Consumer = MC_NPPOOL;
- Pfn1->ReferenceCount = 1;
- Pfn1->LockCount = 0;
+ Pfn1->Consumer = MC_NPPOOL;
+ Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->SavedSwapEntry = 0;
//
// Check if it was already zeroed
//
- if (Pfn1->Flags.Zero == 0)
+ if (Pfn1->u3.e1.PageLocation != ZeroedPageList)
{
//
// It wasn't, so zero it
//
MiZeroPage(MiGetPfnEntryIndex(Pfn1));
}
+
+ //
+ // Mark it in use
+ //
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
//
// Check if this is the last PFN, otherwise go on
@@ -303,8 +302,8 @@
//
// Mark the first and last PFN so we can find them later
//
- Pfn1->Flags.StartOfAllocation = 1;
- (Pfn1 + SizeInPages - 1)->Flags.EndOfAllocation = 1;
+ Pfn1->u3.e1.StartOfAllocation = 1;
+ (Pfn1 + SizeInPages - 1)->u3.e1.EndOfAllocation = 1;
//
// Now it's safe to let go of the PFN lock
@@ -466,18 +465,17 @@
//
// Make sure it's really free
//
- ASSERT(Pfn1->Flags.Type == MM_PHYSICAL_PAGE_FREE);
- ASSERT(Pfn1->ReferenceCount == 0);
+ ASSERT(MiIsPfnInUse(Pfn1) == FALSE);
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
//
// Allocate it and mark it
//
- Pfn1->Flags.Type = MM_PHYSICAL_PAGE_USED;
- Pfn1->Flags.Consumer = MC_NPPOOL;
- Pfn1->Flags.StartOfAllocation = 1;
- Pfn1->Flags.EndOfAllocation = 1;
- Pfn1->ReferenceCount = 1;
- Pfn1->LockCount = 0;
+ Pfn1->Consumer = MC_NPPOOL;
+ Pfn1->u3.e1.StartOfAllocation = 1;
+ Pfn1->u3.e1.EndOfAllocation = 1;
+ Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
Pfn1->SavedSwapEntry = 0;
//
@@ -513,29 +511,27 @@
//
// Make sure it's free and if this is our first pass, zeroed
//
- if (Pfn1->Flags.Type != MM_PHYSICAL_PAGE_FREE) continue;
- if (Pfn1->Flags.Zero != LookForZeroedPages) continue;
+ if (!MiIsPfnInUse(Pfn1)) continue;
+ if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) !=
LookForZeroedPages) continue;
//
// Sanity checks
//
- ASSERT(Pfn1->ReferenceCount == 0);
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
//
// Now setup the page and mark it
//
- Pfn1->Flags.Type = MM_PHYSICAL_PAGE_USED;
- Pfn1->Flags.Consumer = MC_NPPOOL;
- Pfn1->ReferenceCount = 1;
- Pfn1->Flags.StartOfAllocation = 1;
- Pfn1->Flags.EndOfAllocation = 1;
- Pfn1->LockCount = 0;
+ Pfn1->Consumer = MC_NPPOOL;
+ Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u3.e1.StartOfAllocation = 1;
+ Pfn1->u3.e1.EndOfAllocation = 1;
Pfn1->SavedSwapEntry = 0;
//
// If this page was unzeroed, we've consumed such a page
//
- if (!Pfn1->Flags.Zero) UnzeroedPageCount--;
+ if (Pfn1->u3.e1.PageLocation != ZeroedPageList) UnzeroedPageCount--;
//
// Decrease available pages
@@ -603,7 +599,8 @@
//
Pfn1 = MiGetPfnEntry(Page);
ASSERT(Pfn1);
- if (Pfn1->Flags.Zero == 0) MiZeroPage(Page);
+ if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPage(Page);
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
}
//
@@ -620,7 +617,7 @@
{
ULONG i;
PPHYSICAL_PAGE Pfn1;
- PCHAR State = "????", Consumer = "Unknown";
+ PCHAR State = "????", Type = "Unknown";
KIRQL OldIrql;
ULONG Totals[5] = {0}, FreePages = 0;
@@ -637,67 +634,63 @@
//
// Get the consumer
//
- switch (Pfn1->Flags.Consumer)
+ switch (Pfn1->Consumer)
{
case MC_NPPOOL:
- Consumer = "Nonpaged Pool";
+ Type = "Nonpaged Pool";
break;
case MC_PPOOL:
- Consumer = "Paged Pool";
+ Type = "Paged Pool";
break;
case MC_CACHE:
- Consumer = "File System Cache";
+ Type = "File System Cache";
break;
case MC_USER:
- Consumer = "Process Working Set";
+ Type = "Process Working Set";
break;
case MC_SYSTEM:
- Consumer = "System";
+ Type = "System";
break;
}
//
// Get the type
//
- switch (Pfn1->Flags.Type)
+ if (MiIsPfnInUse(Pfn1))
{
- case MM_PHYSICAL_PAGE_USED:
-
- State = "Used";
- Totals[Pfn1->Flags.Consumer]++;
- break;
-
- case MM_PHYSICAL_PAGE_FREE:
-
- State = "Free";
- Consumer = "Free";
- FreePages++;
- break;
+ State = "Used";
+ Totals[Pfn1->Consumer]++;
}
-
+ else
+ {
+ State = "Free";
+ Type = "Free";
+ FreePages++;
+ break;
+ }
+
//
// Pretty-print the page
//
- DbgPrint("0x%08p:\t%04s\t%20s\t(%02d.%02d) [%08p])\n",
+ DbgPrint("0x%08p:\t%04s\t%20s\t(%02d) [%08p])\n",
i << PAGE_SHIFT,
State,
- Consumer,
- Pfn1->ReferenceCount,
- Pfn1->LockCount,
+ Type,
+ Pfn1->u3.e2.ReferenceCount,
Pfn1->RmapListHead);
}
DbgPrint("Nonpaged Pool: %d pages\t[%d KB]\n", Totals[MC_NPPOOL],
(Totals[MC_NPPOOL] << PAGE_SHIFT) / 1024);
- DbgPrint("Paged Pool: %d pages\t[%d KB]\n", Totals[MC_PPOOL],
(Totals[MC_PPOOL] << PAGE_SHIFT) / 1024);
+ DbgPrint("Paged Pool: %d pages\t[%d KB]\n", Totals[MC_PPOOL],
(Totals[MC_PPOOL] << PAGE_SHIFT) / 1024);
DbgPrint("File System Cache: %d pages\t[%d KB]\n", Totals[MC_CACHE],
(Totals[MC_CACHE] << PAGE_SHIFT) / 1024);
DbgPrint("Process Working Set: %d pages\t[%d KB]\n", Totals[MC_USER],
(Totals[MC_USER] << PAGE_SHIFT) / 1024);
DbgPrint("System: %d pages\t[%d KB]\n", Totals[MC_SYSTEM],
(Totals[MC_SYSTEM] << PAGE_SHIFT) / 1024);
@@ -723,9 +716,9 @@
/* This is what a used page looks like */
RtlZeroMemory(&UsedPage, sizeof(UsedPage));
- UsedPage.Flags.Type = MM_PHYSICAL_PAGE_USED;
- UsedPage.Flags.Consumer = MC_NPPOOL;
- UsedPage.ReferenceCount = 1;
+ UsedPage.Consumer = MC_NPPOOL;
+ UsedPage.u3.e1.PageLocation = ActiveAndValid;
+ UsedPage.u3.e2.ReferenceCount = 1;
/* Loop the memory descriptors */
for (NextEntry = KeLoaderBlock->MemoryDescriptorListHead.Flink;
@@ -759,7 +752,7 @@
for (i = 0; i < Md->PageCount; i++)
{
/* Mark it as a free page */
- MmPfnDatabase[0][Md->BasePage + i].Flags.Type =
MM_PHYSICAL_PAGE_FREE;
+ MmPfnDatabase[0][Md->BasePage + i].u3.e1.PageLocation = FreePageList;
InsertTailList(&FreeUnzeroedPageListHead,
&MmPfnDatabase[0][Md->BasePage + i].ListEntry);
UnzeroedPageCount++;
@@ -782,7 +775,7 @@
for (i = MxOldFreeDescriptor.BasePage; i < MxFreeDescriptor->BasePage; i++)
{
/* Ensure this page was not added previously */
- ASSERT(MmPfnDatabase[0][i].Flags.Type == 0);
+ ASSERT(MmPfnDatabase[0][i].Consumer == 0);
/* Mark it as used kernel memory */
MmPfnDatabase[0][i] = UsedPage;
@@ -859,13 +852,8 @@
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Referencing non-used page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- Page->ReferenceCount++;
+
+ Page->u3.e2.ReferenceCount++;
}
ULONG
@@ -881,13 +869,8 @@
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Getting reference count for free page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- RCount = Page->ReferenceCount;
+
+ RCount = Page->u3.e2.ReferenceCount;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(RCount);
@@ -897,10 +880,16 @@
NTAPI
MmIsPageInUse(PFN_TYPE Pfn)
{
-
- DPRINT("MmIsPageInUse(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
-
- return (MiGetPfnEntry(Pfn)->Flags.Type == MM_PHYSICAL_PAGE_USED);
+ return MiIsPfnInUse(MiGetPfnEntry(Pfn));
+}
+
+VOID
+NTAPI
+MiSetConsumer(IN PFN_TYPE Pfn,
+ IN ULONG Type)
+{
+ MiGetPfnEntry(Pfn)->Consumer = Type;
+ MiGetPfnEntry(Pfn)->u3.e1.PageLocation = ActiveAndValid;
}
VOID
@@ -914,45 +903,12 @@
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Dereferencing free page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- if (Page->ReferenceCount == 0)
- {
- DPRINT1("Derefrencing page with reference count 0\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- Page->ReferenceCount--;
- if (Page->ReferenceCount == 0)
+ Page->u3.e2.ReferenceCount--;
+ if (Page->u3.e2.ReferenceCount == 0)
{
MmAvailablePages++;
- if (Page->Flags.Consumer == MC_USER) RemoveEntryList(&Page->ListEntry);
- if (Page->RmapListHead != (LONG)NULL)
- {
- DPRINT1("Freeing page with rmap entries.\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- if (Page->LockCount > 0)
- {
- DPRINT1("Freeing locked page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- if (Page->SavedSwapEntry != 0)
- {
- DPRINT1("Freeing page with swap entry.\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Freeing page with flags %x\n",
- Page->Flags.Type);
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- Page->Flags.Type = MM_PHYSICAL_PAGE_FREE;
- Page->Flags.Consumer = MC_MAXIMUM;
+ if (Page->Consumer == MC_USER) RemoveEntryList(&Page->ListEntry);
+ Page->u3.e1.PageLocation = FreePageList;
InsertTailList(&FreeUnzeroedPageListHead,
&Page->ListEntry);
UnzeroedPageCount++;
@@ -963,73 +919,9 @@
}
}
-ULONG
-NTAPI
-MmGetLockCountPage(PFN_TYPE Pfn)
-{
- KIRQL oldIrql;
- ULONG CurrentLockCount;
- PPHYSICAL_PAGE Page;
-
- DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn <<
PAGE_SHIFT);
-
- oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Getting lock count for free page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- CurrentLockCount = Page->LockCount;
- KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
-
- return(CurrentLockCount);
-}
-
-VOID
-NTAPI
-MmLockPage(PFN_TYPE Pfn)
-{
- PPHYSICAL_PAGE Page;
-
- DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
-
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Locking free page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- Page->LockCount++;
-}
-
-VOID
-NTAPI
-MmUnlockPage(PFN_TYPE Pfn)
-{
- PPHYSICAL_PAGE Page;
-
- DPRINT("MmUnlockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
-
- Page = MiGetPfnEntry(Pfn);
- ASSERT(Page);
- if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Unlocking free page\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- Page->LockCount--;
-}
-
PFN_TYPE
NTAPI
-MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
+MmAllocPage(ULONG Type, SWAPENTRY SwapEntry)
{
PFN_TYPE PfnOffset;
PLIST_ENTRY ListEntry;
@@ -1065,29 +957,19 @@
PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
}
- if (PageDescriptor->Flags.Type != MM_PHYSICAL_PAGE_FREE)
- {
- DPRINT1("Got non-free page from freelist\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- if (PageDescriptor->ReferenceCount != 0)
- {
- DPRINT1("%d\n", PageDescriptor->ReferenceCount);
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
- PageDescriptor->Flags.Consumer = Consumer;
- PageDescriptor->ReferenceCount = 1;
- PageDescriptor->LockCount = 0;
+ PageDescriptor->Consumer = Type;
+ PageDescriptor->u3.e2.ReferenceCount = 1;
PageDescriptor->SavedSwapEntry = SwapEntry;
MmAvailablePages--;
PfnOffset = PageDescriptor - MmPfnDatabase[0];
- if ((NeedClear) && (Consumer != MC_SYSTEM))
+ if ((NeedClear) && (Type != MC_SYSTEM))
{
MiZeroPage(PfnOffset);
}
+
+ PageDescriptor->u3.e1.PageLocation = ActiveAndValid;
return PfnOffset;
}
@@ -1135,11 +1017,6 @@
KernelMode,
FALSE,
NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZeroPageThread: Wait failed\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
if (ZeroPageThreadShouldTerminate)
{
@@ -1154,14 +1031,12 @@
UnzeroedPageCount--;
PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
/* We set the page to used, because MmCreateVirtualMapping failed with unused
pages */
- PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
Pfn = PageDescriptor - MmPfnDatabase[0];
Status = MiZeroPage(Pfn);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- PageDescriptor->Flags.Zero = 1;
- PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE;
+ PageDescriptor->u3.e1.PageLocation = ZeroedPageList;
if (NT_SUCCESS(Status))
{
InsertHeadList(&FreeZeroedPageListHead, ListEntry);