Author: sir_richard
Date: Wed Sep 29 01:10:28 2010
New Revision: 48927
URL: http://svn.reactos.org/svn/reactos?rev=48927&view=rev
Log:
[NTOS]: Add MiRemoveZeroPageSafe helper function, when a zero page is required, but the inline zeroing of MiRemoveZeroPage is not. This function will only try grabbing a zero page if one exists, otherwise a free page will be grabbed and zeroed with custom code of the caller's choosing.
[NTOS]: Add concept of process color and system color. Compute correct color to use whenever requesting a page.
[NTOS]: Uncondtionally enable the color code when inserting/removing pages.
For now, when requesting a page, colors are still ignored, and the global PFN lists are scanned instead. If there are no regressions, we are one patch away from that.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
trunk/reactos/ntoskrnl/mm/ARM3/pool.c
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c
trunk/reactos/ntoskrnl/mm/freelist.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Sep 29 01:10:28 2010
@@ -217,6 +217,13 @@
// Special IRQL value (found in assertions)
//
#define MM_NOIRQL (KIRQL)0xFFFFFFFF
+
+//
+// Returns the color of a page
+//
+#define MI_GET_PAGE_COLOR(x) ((x) & MmSecondaryColorMask)
+#define MI_GET_NEXT_COLOR(x) (MI_GET_PAGE_COLOR(++MmSystemPageColor))
+#define MI_GET_NEXT_PROCESS_COLOR(x) (MI_GET_PAGE_COLOR(++(x)->NextPageColor))
//
// FIXFIX: These should go in ex.h after the pool merge
@@ -455,9 +462,8 @@
extern LIST_ENTRY MmProcessList;
extern BOOLEAN MmZeroingPageThreadActive;
extern KEVENT MmZeroingPageEvent;
-
-#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
-#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
+extern ULONG MmSystemPageColor;
+extern ULONG MmProcessColorSeed;
//
// Figures out the hardware bits for a PTE
@@ -1093,4 +1099,19 @@
IN PMMADDRESS_NODE Node
);
+//
+// MiRemoveZeroPage will use inline code to zero out the page manually if only
+// free pages are available. In some scenarios, we don't/can't run that piece of
+// code and would rather only have a real zero page. If we can't have a zero page,
+// then we'd like to have our own code to grab a free page and zero it out, by
+// using MiRemoveAnyPage. This macro implements this.
+//
+PFN_NUMBER
+FORCEINLINE
+MiRemoveZeroPageSafe(IN ULONG Color)
+{
+ if (MmFreePagesByColor[ZeroedPageList][Color].Flink != LIST_HEAD) return MiRemoveZeroPage(Color);
+ return 0;
+}
+
/* EOF */
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Wed Sep 29 01:10:28 2010
@@ -179,9 +179,10 @@
IN PEPROCESS Process,
IN KIRQL OldIrql)
{
- PFN_NUMBER PageFrameNumber;
+ PFN_NUMBER PageFrameNumber = 0;
MMPTE TempPte;
BOOLEAN NeedZero = FALSE;
+ ULONG Color;
DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n",
Address,
Process);
@@ -196,9 +197,17 @@
/* No forking yet */
ASSERT(Process->ForkInProgress == NULL);
+ /* Get process color */
+ Color = MI_GET_NEXT_PROCESS_COLOR(Process);
+
/* We'll need a zero page */
NeedZero = TRUE;
}
+ else
+ {
+ /* Get the next system page color */
+ Color = MI_GET_NEXT_COLOR();
+ }
//
// Lock the PFN database
@@ -206,9 +215,21 @@
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
ASSERT(PointerPte->u.Hard.Valid == 0);
- /* Get a page */
- PageFrameNumber = MiRemoveAnyPage(0);
- DPRINT("New pool page: %lx\n", PageFrameNumber);
+ /* Do we need a zero page? */
+ if (NeedZero)
+ {
+ /* Try to get one, if we couldn't grab a free page and zero it */
+ PageFrameNumber = MiRemoveZeroPageSafe(Color);
+ if (PageFrameNumber) NeedZero = FALSE;
+ }
+
+ /* Did we get a page? */
+ if (!PageFrameNumber)
+ {
+ /* We either failed to find a zero page, or this is a system request */
+ PageFrameNumber = MiRemoveAnyPage(Color);
+ DPRINT("New pool page: %lx\n", PageFrameNumber);
+ }
/* Initialize it */
MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
@@ -463,6 +484,7 @@
ULONG ProtectionCode;
PMMVAD Vad;
PFN_NUMBER PageFrameIndex;
+ ULONG Color;
DPRINT("ARM3 FAULT AT: %p\n", Address);
//
@@ -756,19 +778,25 @@
/* Lock the PFN database since we're going to grab a page */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-
- /* Grab a page out of there. Later we should grab a colored zero page */
- PageFrameIndex = MiRemoveAnyPage(0);
- ASSERT(PageFrameIndex);
-
- /* Release the lock since we need to do some zeroing */
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
-
- /* Zero out the page, since it's for user-mode */
- MiZeroPfn(PageFrameIndex);
-
- /* Grab the lock again so we can initialize the PFN entry */
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Try to get a zero page */
+ Color = MI_GET_NEXT_PROCESS_COLOR(CurrentProcess);
+ PageFrameIndex = MiRemoveZeroPageSafe(Color);
+ if (!PageFrameIndex)
+ {
+ /* Grab a page out of there. Later we should grab a colored zero page */
+ PageFrameIndex = MiRemoveAnyPage(Color);
+ ASSERT(PageFrameIndex);
+
+ /* Release the lock since we need to do some zeroing */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Zero out the page, since it's for user-mode */
+ MiZeroPfn(PageFrameIndex);
+
+ /* Grab the lock again so we can initialize the PFN entry */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
/* Initialize the PFN entry now */
MiInitializePfn(PageFrameIndex, PointerPte, 1);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Wed Sep 29 01:10:28 2010
@@ -30,12 +30,11 @@
#define ASSERT_LIST_INVARIANT(x)
#endif
-#define ARM3_COLORS 1
-
/* GLOBALS ********************************************************************/
BOOLEAN MmDynamicPfn;
BOOLEAN MmMirroring;
+ULONG MmSystemPageColor;
MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
@@ -80,11 +79,9 @@
PFN_NUMBER OldFlink, OldBlink;
PMMPFNLIST ListHead;
MMLISTS ListName;
-#ifdef ARM3_COLORS
ULONG Color;
PMMCOLOR_TABLES ColorTable;
PMMPFN Pfn1;
-#endif
/* Make sure the PFN lock is held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@@ -131,7 +128,7 @@
/* Set the list head's backlink instead */
ListHead->Flink = OldFlink;
}
-#ifdef ARM3_COLORS
+
/* Get the page color */
OldBlink = MiGetPfnEntryIndex(Entry);
Color = OldBlink & MmSecondaryColorMask;
@@ -185,7 +182,7 @@
/* ReactOS Hack */
Entry->OriginalPte.u.Long = 0;
-#endif
+
/* We are not on a list anymore */
Entry->u1.Flink = Entry->u2.Blink = 0;
ASSERT_LIST_INVARIANT(ListHead);
@@ -219,9 +216,8 @@
MMLISTS ListName;
PFN_NUMBER OldFlink, OldBlink;
ULONG OldColor, OldCache;
-#ifdef ARM3_COLORS
PMMCOLOR_TABLES ColorTable;
-#endif
+
/* Make sure PFN lock is held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(Color < MmSecondaryColors);
@@ -280,7 +276,7 @@
Pfn1->u3.e2.ShortFlags = 0;
Pfn1->u3.e1.PageColor = OldColor;
Pfn1->u3.e1.CacheAttribute = OldCache;
-#ifdef ARM3_COLORS
+
/* Get the first page on the color list */
ASSERT(Color < MmSecondaryColors);
ColorTable = &MmFreePagesByColor[ListName][Color];
@@ -306,7 +302,7 @@
/* ReactOS Hack */
Pfn1->OriginalPte.u.Long = 0;
-#endif
+
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
{
@@ -340,9 +336,8 @@
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(MmAvailablePages != 0);
ASSERT(Color < MmSecondaryColors);
-
+#if 0
/* Check the colored free list */
-#if 0 // Enable when using ARM3 database */
PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
if (PageIndex == LIST_HEAD)
{
@@ -368,11 +363,10 @@
ASSERT(MmZeroedPageListHead.Total == 0);
}
}
-#if 0 // Enable when using ARM3 database */
+#if 0
}
}
#endif
-
/* Remove the page from its list */
PageIndex = MiRemovePageByColor(PageIndex, Color);
@@ -403,7 +397,7 @@
ASSERT(Color < MmSecondaryColors);
/* Check the colored zero list */
-#if 0 // Enable when using ARM3 database */
+#if 0
PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
if (PageIndex == LIST_HEAD)
{
@@ -414,9 +408,10 @@
Color = PageIndex & MmSecondaryColorMask;
if (PageIndex == LIST_HEAD)
{
+ /* This means there's no zero pages, we have to look for free ones */
ASSERT(MmZeroedPageListHead.Total == 0);
Zero = TRUE;
-#if 0 // Enable when using ARM3 database */
+#if 0
/* Check the colored free list */
PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
if (PageIndex == LIST_HEAD)
@@ -432,13 +427,14 @@
/* FIXME: Should check the standby list */
ASSERT(MmZeroedPageListHead.Total == 0);
}
-#if 0 // Enable when using ARM3 database */
+#if 0
}
#endif
}
-#if 0 // Enable when using ARM3 database */
+#if 0
}
#endif
+
/* Sanity checks */
Pfn1 = MiGetPfnEntry(PageIndex);
ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
@@ -468,11 +464,10 @@
PMMPFNLIST ListHead;
PFN_NUMBER LastPage;
PMMPFN Pfn1;
-#ifdef ARM3_COLORS
ULONG Color;
PMMPFN Blink;
PMMCOLOR_TABLES ColorTable;
-#endif
+
/* Make sure the page index is valid */
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
ASSERT((PageFrameIndex != 0) &&
@@ -537,7 +532,7 @@
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
-#ifdef ARM3_COLORS
+
/* Get the page color */
Color = PageFrameIndex & MmSecondaryColorMask;
@@ -571,7 +566,7 @@
/* And increase the count in the colored list */
ColorTable->Count++;
-#endif
+
/* Notify zero page thread if enough pages are on the free list now */
if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
{
@@ -590,10 +585,9 @@
PFN_NUMBER Flink;
PMMPFN Pfn1, Pfn2;
MMLISTS ListName;
-#ifdef ARM3_COLORS
PMMCOLOR_TABLES ColorHead;
ULONG Color;
-#endif
+
/* For free pages, use MiInsertPageInFreeList */
ASSERT(ListHead != &MmFreePageListHead);
@@ -657,7 +651,7 @@
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
-#ifdef ARM3_COLORS
+ /* Sanity checks */
ASSERT(ListName == ZeroedPageList);
ASSERT(Pfn1->u4.InPageError == 0);
@@ -695,7 +689,6 @@
/* One more paged on the colored list */
ColorHead->Count++;
-#endif
}
VOID
@@ -783,7 +776,7 @@
/* Grab a page */
ASSERT_LIST_INVARIANT(&MmFreePageListHead);
ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
- PageFrameIndex = MiRemoveAnyPage(0);
+ PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Write the software PTE */
MI_WRITE_INVALID_PTE(PointerPte, TempPte);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Wed Sep 29 01:10:28 2010
@@ -473,7 +473,7 @@
ASSERT(PointerPte->u.Hard.Valid == 0);
/* Request a page */
- PageFrameNumber = MiRemoveAnyPage(0);
+ PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
#if (_MI_PAGING_LEVELS >= 3)
@@ -768,7 +768,7 @@
do
{
/* Allocate a page */
- PageFrameNumber = MiRemoveAnyPage(0);
+ PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Get the PFN entry for it and fill it out */
Pfn1 = MiGetPfnEntry(PageFrameNumber);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Wed Sep 29 01:10:28 2010
@@ -16,7 +16,9 @@
#define MODULE_INVOLVED_IN_ARM3
#include "../ARM3/miarm.h"
-extern MM_SYSTEMSIZE MmSystemSize;
+/* GLOBALS ********************************************************************/
+
+ULONG MmProcessColorSeed = 0x12345678;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -357,7 +359,7 @@
PointerPte++;
/* Get a page and write the current invalid PTE */
- PageFrameIndex = MiRemoveAnyPage(0);
+ PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
MI_WRITE_INVALID_PTE(PointerPte, InvalidPte);
/* Initialize the PFN entry for this page */
@@ -444,7 +446,7 @@
while (LimitPte >= NewLimitPte)
{
/* Get a page and write the current invalid PTE */
- PageFrameIndex = MiRemoveAnyPage(0);
+ PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
MI_WRITE_INVALID_PTE(LimitPte, InvalidPte);
/* Initialize the PFN entry for this page */
@@ -1058,9 +1060,10 @@
MMPTE TempPte, PdePte;
ULONG PdeOffset;
PMMPTE SystemTable;
-
- /* No page colors yet */
- Process->NextPageColor = 0;
+ ULONG Color;
+
+ /* Choose a process color */
+ Process->NextPageColor = RtlRandom(&MmProcessColorSeed);
/* Setup the hyperspace lock */
KeInitializeSpinLock(&Process->HyperSpaceLock);
@@ -1068,16 +1071,37 @@
/* Lock PFN database */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- /* Get a page for the PDE */
- PdeIndex = MiRemoveAnyPage(0);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- MiZeroPhysicalPage(PdeIndex);
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-
- /* Get a page for hyperspace */
- HyperIndex = MiRemoveAnyPage(0);
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- MiZeroPhysicalPage(HyperIndex);
+ /* Get a zero page for the PDE, if possible */
+ Color = MI_GET_NEXT_PROCESS_COLOR(Process);
+ PdeIndex = MiRemoveZeroPageSafe(Color);
+ if (!PdeIndex)
+ {
+ /* No zero pages, grab a free one */
+ PdeIndex = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(PdeIndex);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Get a zero page for hyperspace, if possible */
+ Color = MI_GET_NEXT_PROCESS_COLOR(Process);
+ HyperIndex = MiRemoveZeroPageSafe(Color);
+ if (!HyperIndex)
+ {
+ /* No zero pages, grab a free one */
+ HyperIndex = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(HyperIndex);
+ }
+ else
+ {
+ /* Release the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ }
/* Switch to phase 1 initialization */
ASSERT(Process->AddressSpaceInitialized == 0);
@@ -1112,7 +1136,6 @@
/* Copy all the kernel mappings */
PdeOffset = MiGetPdeOffset(MmSystemRangeStart);
-
RtlCopyMemory(&SystemTable[PdeOffset],
MiAddressToPde(MmSystemRangeStart),
PAGE_SIZE - PdeOffset * sizeof(MMPTE));
Modified: trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/zeropage.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/zeropage.c [iso-8859-1] Wed Sep 29 01:10:28 2010
@@ -69,8 +69,11 @@
}
PageIndex = MmFreePageListHead.Flink;
+ ASSERT(PageIndex != LIST_HEAD);
Pfn1 = MiGetPfnEntry(PageIndex);
- FreePage = MiRemoveAnyPage(0); // FIXME: Use real color
+ FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));
+
+ /* The first global free page should also be the first on its own list */
if (FreePage != PageIndex)
{
KeBugCheckEx(PFN_LIST_CORRUPT,
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] Wed Sep 29 01:10:28 2010
@@ -604,11 +604,11 @@
if (Type != MC_SYSTEM)
{
- PfnOffset = MiRemoveZeroPage(0);
+ PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
}
else
{
- PfnOffset = MiRemoveAnyPage(0);
+ PfnOffset = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
}
if (!PfnOffset)
Author: sir_richard
Date: Wed Sep 29 00:13:09 2010
New Revision: 48926
URL: http://svn.reactos.org/svn/reactos?rev=48926&view=rev
Log:
[NTOS]: Fix straggling bugs in color table algorithms.
[NTOS]: Enable color tables! Right now pages are merely entering and exiting the tables, the tables themselves are never used for allocations. This will change with further commits.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Sep 29 00:13:09 2010
@@ -194,10 +194,24 @@
#define MM_SYSLDR_BOOT_LOADED (PVOID)0xFFFFFFFF
#define MM_SYSLDR_SINGLE_ENTRY 0x1
+#if defined(_M_IX86) || defined(_M_ARM)
//
// PFN List Sentinel
//
#define LIST_HEAD 0xFFFFFFFF
+
+//
+// Because GCC cannot automatically downcast 0xFFFFFFFF to lesser-width bits,
+// we need a manual definition suited to the number of bits in the PteFrame.
+// This is used as a LIST_HEAD for the colored list
+//
+#define COLORED_LIST_HEAD ((1 << 25) - 1) // 0x1FFFFFF
+#elif defined(_M_AMD64)
+#define LIST_HEAD 0xFFFFFFFFFFFFFFFFLL
+#define COLORED_LIST_HEAD ((1 << 57) - 1) // 0x1FFFFFFFFFFFFFFLL
+#else
+#error Define these please!
+#endif
//
// Special IRQL value (found in assertions)
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Wed Sep 29 00:13:09 2010
@@ -30,6 +30,8 @@
#define ASSERT_LIST_INVARIANT(x)
#endif
+#define ARM3_COLORS 1
+
/* GLOBALS ********************************************************************/
BOOLEAN MmDynamicPfn;
@@ -133,11 +135,9 @@
/* Get the page color */
OldBlink = MiGetPfnEntryIndex(Entry);
Color = OldBlink & MmSecondaryColorMask;
- DPRINT1("Color: %lx\n", Color);
/* Get the first page on the color list */
ColorTable = &MmFreePagesByColor[ListName][Color];
- DPRINT1("Color table: %p %lx\n", ColorTable, ColorTable->Flink);
/* Check if this was was actually the head */
OldFlink = ColorTable->Flink;
@@ -148,7 +148,7 @@
if (ColorTable->Flink != LIST_HEAD)
{
/* And make the previous link point to the head now */
- MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = -1;
+ MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
}
else
{
@@ -159,7 +159,7 @@
else
{
/* This page shouldn't be pointing back to the head */
- ASSERT(Entry->u4.PteFrame != -1);
+ ASSERT(Entry->u4.PteFrame != COLORED_LIST_HEAD);
/* Make the back link point to whoever the next page is */
Pfn1 = MiGetPfnEntry(Entry->u4.PteFrame);
@@ -170,7 +170,7 @@
{
/* Make the back link point to the head */
Pfn1 = MiGetPfnEntry(Entry->OriginalPte.u.Long);
- Pfn1->u4.PteFrame = -1;
+ Pfn1->u4.PteFrame = Entry->u4.PteFrame;
}
else
{
@@ -182,6 +182,9 @@
/* One less colored page */
ASSERT(ColorTable->Count >= 1);
ColorTable->Count--;
+
+ /* ReactOS Hack */
+ Entry->OriginalPte.u.Long = 0;
#endif
/* We are not on a list anymore */
Entry->u1.Flink = Entry->u2.Blink = 0;
@@ -284,8 +287,6 @@
ASSERT(ColorTable->Count >= 1);
/* Set the forward link to whoever we were pointing to */
- DPRINT1("Has RMAP: %lx (link: %lx)\n", Pfn1->u3.e1.ParityError, Pfn1->OriginalPte.u.Long);
- DPRINT1("Color table: %p %lx\n", ColorTable, ColorTable->Flink);
ColorTable->Flink = Pfn1->OriginalPte.u.Long;
/* Get the first page on the color list */
@@ -297,11 +298,14 @@
else
{
/* The list is empty, so we are the first page */
- MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = -1;
+ MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
}
/* One less page */
ColorTable->Count--;
+
+ /* ReactOS Hack */
+ Pfn1->OriginalPte.u.Long = 0;
#endif
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
@@ -536,16 +540,13 @@
#ifdef ARM3_COLORS
/* Get the page color */
Color = PageFrameIndex & MmSecondaryColorMask;
- DPRINT1("Color: %lx\n", Color);
/* Get the first page on the color list */
ColorTable = &MmFreePagesByColor[FreePageList][Color];
- DPRINT1("Color table: %p %lx\n", ColorTable, ColorTable->Flink);
- DPRINT1("Has RMAP: %lx (link: %lx)\n", Pfn1->u3.e1.ParityError, Pfn1->OriginalPte.u.Long);
if (ColorTable->Flink == LIST_HEAD)
{
/* The list is empty, so we are the first page */
- Pfn1->u4.PteFrame = -1;
+ Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
ColorTable->Flink = PageFrameIndex;
}
else
@@ -557,7 +558,6 @@
Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
/* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
- DPRINT1("Has RMAP: %lx (link: %lx)\n", Blink->u3.e1.ParityError, Blink->OriginalPte.u.Long);
ASSERT(Blink->u3.e1.ParityError == FALSE);
Blink->OriginalPte.u.Long = PageFrameIndex;
}
@@ -663,7 +663,6 @@
/* Get the page color */
Color = PageFrameIndex & MmSecondaryColorMask;
- DPRINT1("Color: %lx\n", Color);
/* Get the list for this color */
ColorHead = &MmFreePagesByColor[ZeroedPageList][Color];
@@ -676,7 +675,7 @@
/* Make this page point back to the list, and point forwards to the old head */
Pfn1->OriginalPte.u.Long = Flink;
- Pfn1->u4.PteFrame = -1;
+ Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
/* Set the new head */
ColorHead->Flink = PageFrameIndex;
@@ -849,7 +848,7 @@
* ways we shouldn't be seeing RMAP entries at this point
*/
ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
- ASSERT(Pfn1->OriginalPte.u.Long == 0);
+ ASSERT(Pfn1->u3.e1.ParityError == FALSE);
/* Mark the page temporarily as valid, we're going to make it free soon */
Pfn1->u3.e1.PageLocation = ActiveAndValid;
Author: sir_richard
Date: Tue Sep 28 22:41:46 2010
New Revision: 48925
URL: http://svn.reactos.org/svn/reactos?rev=48925&view=rev
Log:
[NTOS]: Write missing color code in certain PFN functions, and fix existing code where needed. Add some debugging. For now, turned off until testing succeeds.
[NTOS]: Redocument which MMPFN fields are violated by ReactOS-internal values. This has gotten much better than before.
Modified:
trunk/reactos/ntoskrnl/include/internal/mm.h
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Tue Sep 28 22:41:46 2010
@@ -306,30 +306,30 @@
USHORT Modified:1;
USHORT ReadInProgress:1; // StartOfAllocation
USHORT WriteInProgress:1; // EndOfAllocation
- USHORT PrototypePte:1; // Zero
- USHORT PageColor:4; // LockCount
- USHORT PageLocation:3; // Consumer
+ USHORT PrototypePte:1;
+ USHORT PageColor:4;
+ USHORT PageLocation:3;
USHORT RemovalRequested:1;
- USHORT CacheAttribute:2; // Type
+ USHORT CacheAttribute:2;
USHORT Rom:1;
- USHORT ParityError:1;
+ USHORT ParityError:1; // HasRmap
} MMPFNENTRY;
typedef struct _MMPFN
{
union
{
- PFN_NUMBER Flink; // ListEntry.Flink
- ULONG WsIndex;
+ PFN_NUMBER Flink;
+ ULONG WsIndex; // SavedSwapEntry
PKEVENT Event;
NTSTATUS ReadStatus;
SINGLE_LIST_ENTRY NextStackPfn;
} u1;
- PMMPTE PteAddress; // ListEntry.Blink
+ PMMPTE PteAddress;
union
{
PFN_NUMBER Blink;
- ULONG_PTR ShareCount; // MapCount
+ ULONG_PTR ShareCount;
} u2;
union
{
@@ -351,7 +351,7 @@
};
union
{
- ULONG_PTR EntireFrame; // SavedSwapEntry
+ ULONG_PTR EntireFrame;
struct
{
ULONG_PTR PteFrame:25;
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Tue Sep 28 22:41:46 2010
@@ -933,12 +933,6 @@
IN PMMPFN Entry
);
-PMMPFN
-NTAPI
-MiRemoveHeadList(
- IN PMMPFNLIST ListHead
-);
-
PFN_NUMBER
NTAPI
MiAllocatePfn(
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Tue Sep 28 22:41:46 2010
@@ -78,6 +78,11 @@
PFN_NUMBER OldFlink, OldBlink;
PMMPFNLIST ListHead;
MMLISTS ListName;
+#ifdef ARM3_COLORS
+ ULONG Color;
+ PMMCOLOR_TABLES ColorTable;
+ PMMPFN Pfn1;
+#endif
/* Make sure the PFN lock is held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@@ -124,13 +129,64 @@
/* Set the list head's backlink instead */
ListHead->Flink = OldFlink;
}
-
+#ifdef ARM3_COLORS
+ /* Get the page color */
+ OldBlink = MiGetPfnEntryIndex(Entry);
+ Color = OldBlink & MmSecondaryColorMask;
+ DPRINT1("Color: %lx\n", Color);
+
+ /* Get the first page on the color list */
+ ColorTable = &MmFreePagesByColor[ListName][Color];
+ DPRINT1("Color table: %p %lx\n", ColorTable, ColorTable->Flink);
+
+ /* Check if this was was actually the head */
+ OldFlink = ColorTable->Flink;
+ if (OldFlink == OldBlink)
+ {
+ /* Make the table point to the next page this page was linking to */
+ ColorTable->Flink = Entry->OriginalPte.u.Long;
+ if (ColorTable->Flink != LIST_HEAD)
+ {
+ /* And make the previous link point to the head now */
+ MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = -1;
+ }
+ else
+ {
+ /* And if that page was the head, loop the list back around */
+ ColorTable->Blink = (PVOID)LIST_HEAD;
+ }
+ }
+ else
+ {
+ /* This page shouldn't be pointing back to the head */
+ ASSERT(Entry->u4.PteFrame != -1);
+
+ /* Make the back link point to whoever the next page is */
+ Pfn1 = MiGetPfnEntry(Entry->u4.PteFrame);
+ Pfn1->OriginalPte.u.Long = Entry->OriginalPte.u.Long;
+
+ /* Check if this page was pointing to the head */
+ if (Entry->OriginalPte.u.Long != LIST_HEAD)
+ {
+ /* Make the back link point to the head */
+ Pfn1 = MiGetPfnEntry(Entry->OriginalPte.u.Long);
+ Pfn1->u4.PteFrame = -1;
+ }
+ else
+ {
+ /* Then the table is directly back pointing to this page now */
+ ColorTable->Blink = Pfn1;
+ }
+ }
+
+ /* One less colored page */
+ ASSERT(ColorTable->Count >= 1);
+ ColorTable->Count--;
+#endif
/* We are not on a list anymore */
Entry->u1.Flink = Entry->u2.Blink = 0;
ASSERT_LIST_INVARIANT(ListHead);
- /* FIXME: Deal with color list */
-
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
{
@@ -160,9 +216,9 @@
MMLISTS ListName;
PFN_NUMBER OldFlink, OldBlink;
ULONG OldColor, OldCache;
-#if 0
+#ifdef ARM3_COLORS
PMMCOLOR_TABLES ColorTable;
-#endif
+#endif
/* Make sure PFN lock is held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(Color < MmSecondaryColors);
@@ -221,18 +277,22 @@
Pfn1->u3.e2.ShortFlags = 0;
Pfn1->u3.e1.PageColor = OldColor;
Pfn1->u3.e1.CacheAttribute = OldCache;
-
-#if 0 // When switching to ARM3
+#ifdef ARM3_COLORS
/* Get the first page on the color list */
+ ASSERT(Color < MmSecondaryColors);
ColorTable = &MmFreePagesByColor[ListName][Color];
ASSERT(ColorTable->Count >= 1);
/* Set the forward link to whoever we were pointing to */
+ DPRINT1("Has RMAP: %lx (link: %lx)\n", Pfn1->u3.e1.ParityError, Pfn1->OriginalPte.u.Long);
+ DPRINT1("Color table: %p %lx\n", ColorTable, ColorTable->Flink);
ColorTable->Flink = Pfn1->OriginalPte.u.Long;
+
+ /* Get the first page on the color list */
if (ColorTable->Flink == LIST_HEAD)
{
/* This is the beginning of the list, so set the sentinel value */
- ColorTable->Blink = LIST_HEAD;
+ ColorTable->Blink = (PVOID)LIST_HEAD;
}
else
{
@@ -240,8 +300,8 @@
MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = -1;
}
- /* One more page */
- ColorTable->Total++;
+ /* One less page */
+ ColorTable->Count--;
#endif
/* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold)
@@ -404,7 +464,7 @@
PMMPFNLIST ListHead;
PFN_NUMBER LastPage;
PMMPFN Pfn1;
-#if 0
+#ifdef ARM3_COLORS
ULONG Color;
PMMPFN Blink;
PMMCOLOR_TABLES ColorTable;
@@ -473,13 +533,15 @@
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
-
-#if 0 // When using ARM3 PFN
+#ifdef ARM3_COLORS
/* Get the page color */
Color = PageFrameIndex & MmSecondaryColorMask;
+ DPRINT1("Color: %lx\n", Color);
/* Get the first page on the color list */
ColorTable = &MmFreePagesByColor[FreePageList][Color];
+ DPRINT1("Color table: %p %lx\n", ColorTable, ColorTable->Flink);
+ DPRINT1("Has RMAP: %lx (link: %lx)\n", Pfn1->u3.e1.ParityError, Pfn1->OriginalPte.u.Long);
if (ColorTable->Flink == LIST_HEAD)
{
/* The list is empty, so we are the first page */
@@ -492,18 +554,24 @@
Blink = (PMMPFN)ColorTable->Blink;
/* Make it link to us */
- Pfn1->u4.PteFrame = MI_PFNENTRY_TO_PFN(Blink);
+ Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
+
+ /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
+ DPRINT1("Has RMAP: %lx (link: %lx)\n", Blink->u3.e1.ParityError, Blink->OriginalPte.u.Long);
+ ASSERT(Blink->u3.e1.ParityError == FALSE);
Blink->OriginalPte.u.Long = PageFrameIndex;
}
/* Now initialize our own list pointers */
ColorTable->Blink = Pfn1;
+
+ /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
+ ASSERT(Pfn1->u3.e1.ParityError == FALSE);
Pfn1->OriginalPte.u.Long = LIST_HEAD;
/* And increase the count in the colored list */
ColorTable->Count++;
#endif
-
/* Notify zero page thread if enough pages are on the free list now */
if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
{
@@ -522,7 +590,10 @@
PFN_NUMBER Flink;
PMMPFN Pfn1, Pfn2;
MMLISTS ListName;
-
+#ifdef ARM3_COLORS
+ PMMCOLOR_TABLES ColorHead;
+ ULONG Color;
+#endif
/* For free pages, use MiInsertPageInFreeList */
ASSERT(ListHead != &MmFreePageListHead);
@@ -585,8 +656,47 @@
/* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
}
-
- /* FIXME: Color code handling */
+
+#ifdef ARM3_COLORS
+ ASSERT(ListName == ZeroedPageList);
+ ASSERT(Pfn1->u4.InPageError == 0);
+
+ /* Get the page color */
+ Color = PageFrameIndex & MmSecondaryColorMask;
+ DPRINT1("Color: %lx\n", Color);
+
+ /* Get the list for this color */
+ ColorHead = &MmFreePagesByColor[ZeroedPageList][Color];
+
+ /* Get the old head */
+ Flink = ColorHead->Flink;
+
+ /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
+ ASSERT(Pfn1->u3.e1.ParityError == FALSE);
+
+ /* Make this page point back to the list, and point forwards to the old head */
+ Pfn1->OriginalPte.u.Long = Flink;
+ Pfn1->u4.PteFrame = -1;
+
+ /* Set the new head */
+ ColorHead->Flink = PageFrameIndex;
+
+ /* Was the head empty? */
+ if (Flink != LIST_HEAD)
+ {
+ /* No, so make the old head point to this page */
+ Pfn2 = MiGetPfnEntry(Flink);
+ Pfn2->u4.PteFrame = PageFrameIndex;
+ }
+ else
+ {
+ /* Yes, make it loop back to this page */
+ ColorHead->Blink = (PVOID)Pfn1;
+ }
+
+ /* One more paged on the colored list */
+ ColorHead->Count++;
+#endif
}
VOID