Author: ros-arm-bringup
Date: Thu Feb 14 18:36:12 2008
New Revision: 32356
URL:
http://svn.reactos.org/svn/reactos?rev=32356&view=rev
Log:
The Memory Manager design dictated that every page must be on a linked list, so that it
can be removed from that list when dereferenced, and inserted on the free list. This
wasn't optimal, because the UsedPageListHead was actually not used for anything else
than working set and user-page LRU. Nevertheless, every single page on the system would be
on a list (such as the non-pool memory list), even if those lists were ignored. Those
lists are all gone now, replaced by the UsedPageListHead. Likewise, the BIOS page list has
also been removed.
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 (original)
+++ trunk/reactos/ntoskrnl/mm/balance.c Thu Feb 14 18:36:12 2008
@@ -263,7 +263,7 @@
{
KEBUGCHECK(NO_PAGES_AVAILABLE);
}
- MmTransferOwnershipPage(Page, Consumer);
+ MmSetLRULastPage(Page);
*AllocatedPage = Page;
(void)InterlockedDecrementUL(&MiPagesRequired);
return(STATUS_SUCCESS);
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 (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c Thu Feb 14 18:36:12 2008
@@ -56,10 +56,9 @@
ULONG MmPageArraySize;
static KSPIN_LOCK PageListLock;
-static LIST_ENTRY UsedPageListHeads[MC_MAXIMUM];
+static LIST_ENTRY UserPageListHead;
static LIST_ENTRY FreeZeroedPageListHead;
static LIST_ENTRY FreeUnzeroedPageListHead;
-static LIST_ENTRY BiosPageListHead;
static KEVENT ZeroPageThreadEvent;
static BOOLEAN ZeroPageThreadShouldTerminate = FALSE;
@@ -68,36 +67,6 @@
/* FUNCTIONS *************************************************************/
-VOID
-NTAPI
-MmTransferOwnershipPage(PFN_TYPE Pfn, ULONG NewConsumer)
-{
- KIRQL oldIrql;
-
- KeAcquireSpinLock(&PageListLock, &oldIrql);
- if (MmPageArray[Pfn].MapCount != 0)
- {
- DPRINT1("Transfering mapped page.\n");
- KEBUGCHECK(0);
- }
- if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
- {
- DPRINT1("Type: %d\n", MmPageArray[Pfn].Flags.Type);
- KEBUGCHECK(0);
- }
- if (MmPageArray[Pfn].ReferenceCount != 1)
- {
- DPRINT1("ReferenceCount: %d\n", MmPageArray[Pfn].ReferenceCount);
- KEBUGCHECK(0);
- }
- RemoveEntryList(&MmPageArray[Pfn].ListEntry);
- InsertTailList(&UsedPageListHeads[NewConsumer],
- &MmPageArray[Pfn].ListEntry);
- MmPageArray[Pfn].Flags.Consumer = NewConsumer;
- KeReleaseSpinLock(&PageListLock, oldIrql);
- MiZeroPage(Pfn);
-}
-
PFN_TYPE
NTAPI
MmGetLRUFirstUserPage(VOID)
@@ -107,8 +76,8 @@
KIRQL oldIrql;
KeAcquireSpinLock(&PageListLock, &oldIrql);
- NextListEntry = UsedPageListHeads[MC_USER].Flink;
- if (NextListEntry == &UsedPageListHeads[MC_USER])
+ NextListEntry = UserPageListHead.Flink;
+ if (NextListEntry == &UserPageListHead)
{
KeReleaseSpinLock(&PageListLock, oldIrql);
return 0;
@@ -130,7 +99,7 @@
MmPageArray[Pfn].Flags.Consumer == MC_USER)
{
RemoveEntryList(&MmPageArray[Pfn].ListEntry);
- InsertTailList(&UsedPageListHeads[MC_USER],
+ InsertTailList(&UserPageListHead,
&MmPageArray[Pfn].ListEntry);
}
KeReleaseSpinLock(&PageListLock, oldIrql);
@@ -148,13 +117,13 @@
if (MmPageArray[PreviousPfn].Flags.Type != MM_PHYSICAL_PAGE_USED ||
MmPageArray[PreviousPfn].Flags.Consumer != MC_USER)
{
- NextListEntry = UsedPageListHeads[MC_USER].Flink;
+ NextListEntry = UserPageListHead.Flink;
}
else
{
NextListEntry = MmPageArray[PreviousPfn].ListEntry.Flink;
}
- if (NextListEntry == &UsedPageListHeads[MC_USER])
+ if (NextListEntry == &UserPageListHead)
{
KeReleaseSpinLock(&PageListLock, oldIrql);
return 0;
@@ -245,8 +214,6 @@
MmPageArray[i].LockCount = 0;
MmPageArray[i].MapCount = 0;
MmPageArray[i].SavedSwapEntry = 0;
- InsertTailList(&UsedPageListHeads[MC_NPPOOL],
- &MmPageArray[i].ListEntry);
}
KeReleaseSpinLock(&PageListLock, oldIrql);
for (i = start; i < (start + length); i++)
@@ -328,10 +295,9 @@
ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
KeInitializeSpinLock(&PageListLock);
- for (i = 0; i < MC_MAXIMUM; i++) InitializeListHead(&UsedPageListHeads[i]);
+ InitializeListHead(&UserPageListHead);
InitializeListHead(&FreeUnzeroedPageListHead);
InitializeListHead(&FreeZeroedPageListHead);
- InitializeListHead(&BiosPageListHead);
LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
LastPhysKernelAddress = (ULONG_PTR)PAGE_ROUND_UP(LastPhysKernelAddress);
@@ -340,7 +306,6 @@
MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress;
Reserved = PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE;
- DPRINT("Reserved %d\n", Reserved);
LastKernelAddress = ((ULONG_PTR)LastKernelAddress + (Reserved * PAGE_SIZE));
LastPhysKernelAddress = (ULONG_PTR)LastPhysKernelAddress + (Reserved * PAGE_SIZE);
@@ -353,6 +318,7 @@
{
PVOID Address = (char*)MmPageArray + (i * PAGE_SIZE);
ULONG j, start, end;
+
if (!MmIsPagePresent(NULL, Address))
{
PFN_TYPE Pfn;
@@ -388,6 +354,7 @@
/* Setting the page protection is necessary to set the global bit on IA32 */
MmSetPageProtect(NULL, Address, PAGE_READWRITE);
}
+
memset(Address, 0, PAGE_SIZE);
start = ((ULONG_PTR)Address - (ULONG_PTR)MmPageArray) / sizeof(PHYSICAL_PAGE);
@@ -406,8 +373,6 @@
MmPageArray[0].Flags.Consumer = MC_NPPOOL;
MmPageArray[0].Flags.Zero = 0;
MmPageArray[0].ReferenceCount = 0;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[0].ListEntry);
MmStats.NrReservedPages++;
}
else if (j == 1)
@@ -420,8 +385,6 @@
MmPageArray[1].Flags.Consumer = MC_NPPOOL;
MmPageArray[1].Flags.Zero = 0;
MmPageArray[1].ReferenceCount = 0;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[1].ListEntry);
MmStats.NrReservedPages++;
}
else if (j == 2)
@@ -433,8 +396,6 @@
MmPageArray[2].Flags.Consumer = MC_NPPOOL;
MmPageArray[2].Flags.Zero = 0;
MmPageArray[2].ReferenceCount = 0;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[2].ListEntry);
MmStats.NrReservedPages++;
}
/* Protect the Page Directory. This will be changed in r3 */
@@ -444,8 +405,6 @@
MmPageArray[j].Flags.Zero = 0;
MmPageArray[j].Flags.Consumer = MC_NPPOOL;
MmPageArray[j].ReferenceCount = 1;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[j].ListEntry);
MmStats.NrReservedPages++;
}
else if (j >= 0xa0000 / PAGE_SIZE && j < 0x100000 /
PAGE_SIZE)
@@ -454,8 +413,6 @@
MmPageArray[j].Flags.Zero = 0;
MmPageArray[j].Flags.Consumer = MC_NPPOOL;
MmPageArray[j].ReferenceCount = 1;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[j].ListEntry);
MmStats.NrReservedPages++;
}
else if (j >= (ULONG)FirstPhysKernelAddress/PAGE_SIZE &&
@@ -468,8 +425,6 @@
MapCount as well. */
MmPageArray[j].ReferenceCount = 2;
MmPageArray[j].MapCount = 1;
- InsertTailList(&UsedPageListHeads[MC_NPPOOL],
- &MmPageArray[j].ListEntry);
MmStats.NrSystemPages++;
}
else
@@ -489,8 +444,6 @@
MmPageArray[j].Flags.Consumer = MC_NPPOOL;
MmPageArray[j].Flags.Zero = 0;
MmPageArray[j].ReferenceCount = 0;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[j].ListEntry);
MmStats.NrReservedPages++;
}
}
@@ -508,8 +461,6 @@
MmPageArray[i].Flags.Consumer = MC_NPPOOL;
MmPageArray[i].ReferenceCount = 2;
MmPageArray[i].MapCount = 1;
- InsertTailList(&UsedPageListHeads[MC_NPPOOL],
- &MmPageArray[i].ListEntry);
MmStats.NrSystemPages++;
}
else
@@ -518,8 +469,6 @@
MmPageArray[i].Flags.Consumer = MC_NPPOOL;
MmPageArray[i].Flags.Zero = 0;
MmPageArray[i].ReferenceCount = 0;
- InsertTailList(&BiosPageListHead,
- &MmPageArray[i].ListEntry);
MmStats.NrReservedPages++;
}
}
@@ -764,7 +713,7 @@
{
MmStats.NrFreePages++;
MmStats.NrSystemPages--;
- RemoveEntryList(&MmPageArray[Pfn].ListEntry);
+ if (MmPageArray[Pfn].Flags.Consumer == MC_USER)
RemoveEntryList(&MmPageArray[Pfn].ListEntry);
if (MmPageArray[Pfn].RmapListHead != NULL)
{
DPRINT1("Freeing page with rmap entries.\n");
@@ -953,7 +902,6 @@
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = SavedSwapEntry;
- InsertTailList(&UsedPageListHeads[Consumer], ListEntry);
MmStats.NrSystemPages++;
MmStats.NrFreePages--;
@@ -961,6 +909,7 @@
KeReleaseSpinLock(&PageListLock, oldIrql);
PfnOffset = PageDescriptor - MmPageArray;
+ MmSetLRULastPage(PfnOffset);
if (NeedClear)
{
MiZeroPage(PfnOffset);
@@ -1053,7 +1002,6 @@
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = 0; /* FIXME: Do we need swap entries? */
- InsertTailList(&UsedPageListHeads[Consumer],
&PageDescriptor->ListEntry);
MmStats.NrSystemPages++;
MmStats.NrFreePages--;
@@ -1061,6 +1009,7 @@
/* Remember the page */
pfn = PageDescriptor - MmPageArray;
Pages[NumberOfPagesFound++] = pfn;
+ MmSetLRULastPage(pfn);
}
}
else
@@ -1087,8 +1036,6 @@
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = 0; /* FIXME: Do we need swap entries? */
- RemoveEntryList(&PageDescriptor->ListEntry);
- InsertTailList(&UsedPageListHeads[Consumer],
&PageDescriptor->ListEntry);
if (!PageDescriptor->Flags.Zero)
UnzeroedPageCount--;
@@ -1097,6 +1044,7 @@
/* Remember the page */
Pages[NumberOfPagesFound++] = pfn;
+ MmSetLRULastPage(pfn);
if (NumberOfPagesFound == NumberOfPages)
break;
}