- Remove MmGetPageFlags and MmSetPageFlags, there are no consumers of these two functions.

- Get rid of PHYSICAL_PAGE structure and move to WinNT MMPFN structure instead:
  - Define a preprocessor legacy mapping so that freelist.c receives only minimal changes:
    - This mapping allows the old meanings of the PHYSICAL_PAGE fields to remain, but now part of the new MMPFN structure
    - Other modules (balance.c and mm.h) use the new structure directly, since only 3 lines of code required changes.
  - The NT structure is 8 bytes smaller than the ReactOS structure, which saves about 1MB of physical memory and kernel VA space
    for each 512MB of RAM, or 25% less. This also enables ReactOS to support 25% more memory than before (64GB instead of 48GB).


svn path=/trunk/; revision=41503
This commit is contained in:
ReactOS Portable Systems Group 2009-06-21 03:57:42 +00:00
parent 66a0e71bf5
commit 4fbc4ba227
4 changed files with 99 additions and 74 deletions

View file

@ -289,30 +289,68 @@ typedef struct
ULONG PagingRequestsInLastFifteenMinutes; ULONG PagingRequestsInLastFifteenMinutes;
} MM_STATS; } MM_STATS;
typedef struct _PHYSICAL_PAGE typedef struct _MMPFNENTRY
{ {
USHORT Modified:1;
USHORT ReadInProgress:1; // StartOfAllocation
USHORT WriteInProgress:1; // EndOfAllocation
USHORT PrototypePte:1; // Zero
USHORT PageColor:4; // LockCount
USHORT PageLocation:3; // Consumer
USHORT RemovalRequested:1;
USHORT CacheAttribute:2; // Type
USHORT Rom:1;
USHORT ParityError:1;
} MMPFNENTRY;
typedef struct _MMPFN
{
union
{
PFN_NUMBER Flink; // ListEntry.Flink
ULONG WsIndex;
PKEVENT Event;
NTSTATUS ReadStatus;
SINGLE_LIST_ENTRY NextStackPfn;
} u1;
PMMPTE PteAddress; // ListEntry.Blink
union
{
PFN_NUMBER Blink;
ULONG_PTR ShareCount; // MapCount
} u2;
union union
{ {
struct struct
{ {
ULONG Type: 2; USHORT ReferenceCount; // ReferenceCount
ULONG Consumer: 3; MMPFNENTRY e1;
ULONG Zero: 1; };
ULONG StartOfAllocation: 1; struct
ULONG EndOfAllocation: 1; {
} USHORT ReferenceCount;
Flags; USHORT ShortFlags;
ULONG AllFlags; } e2;
} u3;
union
{
MMPTE OriginalPte;
LONG AweReferenceCount; // RmapListHead
}; };
union
LIST_ENTRY ListEntry; {
ULONG ReferenceCount; ULONG_PTR EntireFrame; // SavedSwapEntry
SWAPENTRY SavedSwapEntry; struct
ULONG LockCount; {
ULONG MapCount; ULONG_PTR PteFrame:25;
struct _MM_RMAP_ENTRY* RmapListHead; ULONG_PTR InPageError:1;
} ULONG_PTR VerifierAllocation:1;
PHYSICAL_PAGE, *PPHYSICAL_PAGE; ULONG_PTR AweAllocation:1;
ULONG_PTR Priority:3;
ULONG_PTR MustBeCached:1;
};
} u4;
} MMPFN, *PMMPFN;
extern MM_STATS MmStats; extern MM_STATS MmStats;
@ -991,14 +1029,14 @@ MmPageOutPhysicalAddress(PFN_TYPE Page);
/* freelist.c **********************************************************/ /* freelist.c **********************************************************/
#define ASSERT_PFN(x) ASSERT((x)->Flags.Type != 0) #define ASSERT_PFN(x) ASSERT((x)->u3.e1.CacheAttribute != 0)
FORCEINLINE FORCEINLINE
PPHYSICAL_PAGE PMMPFN
MiGetPfnEntry(IN PFN_TYPE Pfn) MiGetPfnEntry(IN PFN_TYPE Pfn)
{ {
PPHYSICAL_PAGE Page; PMMPFN Page;
extern PPHYSICAL_PAGE MmPageArray; extern PMMPFN MmPageArray;
extern ULONG MmPageArraySize; extern ULONG MmPageArraySize;
/* Mark MmPageArraySize as unreferenced, otherwise it will appear as an unused variable on a Release build */ /* Mark MmPageArraySize as unreferenced, otherwise it will appear as an unused variable on a Release build */
@ -1278,16 +1316,6 @@ BOOLEAN
NTAPI NTAPI
MmIsPageInUse(PFN_TYPE Page); MmIsPageInUse(PFN_TYPE Page);
VOID
NTAPI
MmSetFlagsPage(
PFN_TYPE Page,
ULONG Flags);
ULONG
NTAPI
MmGetFlagsPage(PFN_TYPE Page);
VOID VOID
NTAPI NTAPI
MmSetSavedSwapEntryPage( MmSetSavedSwapEntryPage(

View file

@ -277,7 +277,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
KeBugCheck(NO_PAGES_AVAILABLE); KeBugCheck(NO_PAGES_AVAILABLE);
} }
/* Update the Consumer */ /* Update the Consumer */
MiGetPfnEntry(Page)->Flags.Consumer = Consumer; MiGetPfnEntry(Page)->u3.e1.PageLocation = Consumer;
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page; *AllocatedPage = Page;
(void)InterlockedDecrementUL(&MiPagesRequired); (void)InterlockedDecrementUL(&MiPagesRequired);

View file

@ -27,6 +27,27 @@
/* GLOBALS ****************************************************************/ /* GLOBALS ****************************************************************/
//
//
// ReactOS to NT Physical Page Descriptor Entry Legacy Mapping Definitions
//
// REACTOS NT
//
#define Consumer PageLocation
#define Type CacheAttribute
#define Zero PrototypePte
#define LockCount u3.e1.PageColor
#define MapCount u2.ShareCount
#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
#define PHYSICAL_PAGE MMPFN
#define PPHYSICAL_PAGE PMMPFN
PPHYSICAL_PAGE MmPageArray; PPHYSICAL_PAGE MmPageArray;
ULONG MmPageArraySize; ULONG MmPageArraySize;
@ -94,7 +115,7 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn)
Page = MiGetPfnEntry(PreviousPfn); Page = MiGetPfnEntry(PreviousPfn);
ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED);
ASSERT(Page->Flags.Consumer == MC_USER); ASSERT(Page->Flags.Consumer == MC_USER);
NextListEntry = Page->ListEntry.Flink; NextListEntry = (PLIST_ENTRY)Page->ListEntry.Flink;
if (NextListEntry == &UserPageListHead) if (NextListEntry == &UserPageListHead)
{ {
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
@ -295,10 +316,12 @@ MmInitializePageList(VOID)
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead; NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
NextEntry = NextEntry->Flink) NextEntry = NextEntry->Flink)
{ {
#undef ListEntry
/* Get the descriptor */ /* Get the descriptor */
Md = CONTAINING_RECORD(NextEntry, Md = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry); ListEntry);
#define ListEntry u1
/* Skip bad memory */ /* Skip bad memory */
if ((Md->MemoryType == LoaderFirmwarePermanent) || if ((Md->MemoryType == LoaderFirmwarePermanent) ||
@ -366,17 +389,6 @@ MmInitializePageList(VOID)
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages); MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
} }
VOID
NTAPI
MmSetFlagsPage(PFN_TYPE Pfn, ULONG Flags)
{
KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiGetPfnEntry(Pfn)->AllFlags = Flags;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
VOID VOID
NTAPI NTAPI
MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead) MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead)
@ -384,7 +396,7 @@ MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead)
KIRQL oldIrql; KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiGetPfnEntry(Pfn)->RmapListHead = ListHead; MiGetPfnEntry(Pfn)->RmapListHead = (LONG)ListHead;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
} }
@ -396,7 +408,7 @@ MmGetRmapListHeadPage(PFN_TYPE Pfn)
struct _MM_RMAP_ENTRY* ListHead; struct _MM_RMAP_ENTRY* ListHead;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
ListHead = MiGetPfnEntry(Pfn)->RmapListHead; ListHead = (struct _MM_RMAP_ENTRY*)MiGetPfnEntry(Pfn)->RmapListHead;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(ListHead); return(ListHead);
@ -451,29 +463,14 @@ MmMarkPageUnmapped(PFN_TYPE Pfn)
} }
} }
ULONG
NTAPI
MmGetFlagsPage(PFN_TYPE Pfn)
{
KIRQL oldIrql;
ULONG Flags;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Flags = MiGetPfnEntry(Pfn)->AllFlags;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(Flags);
}
VOID VOID
NTAPI NTAPI
MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SavedSwapEntry) MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SwapEntry)
{ {
KIRQL oldIrql; KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiGetPfnEntry(Pfn)->SavedSwapEntry = SavedSwapEntry; MiGetPfnEntry(Pfn)->SavedSwapEntry = SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
} }
@ -481,14 +478,14 @@ SWAPENTRY
NTAPI NTAPI
MmGetSavedSwapEntryPage(PFN_TYPE Pfn) MmGetSavedSwapEntryPage(PFN_TYPE Pfn)
{ {
SWAPENTRY SavedSwapEntry; SWAPENTRY SwapEntry;
KIRQL oldIrql; KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
SavedSwapEntry = MiGetPfnEntry(Pfn)->SavedSwapEntry; SwapEntry = MiGetPfnEntry(Pfn)->SavedSwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(SavedSwapEntry); return(SwapEntry);
} }
VOID VOID
@ -591,7 +588,7 @@ MmDereferencePage(PFN_TYPE Pfn)
MmStats.NrFreePages++; MmStats.NrFreePages++;
MmStats.NrSystemPages--; MmStats.NrSystemPages--;
if (Page->Flags.Consumer == MC_USER) RemoveEntryList(&Page->ListEntry); if (Page->Flags.Consumer == MC_USER) RemoveEntryList(&Page->ListEntry);
if (Page->RmapListHead != NULL) if (Page->RmapListHead != (LONG)NULL)
{ {
DPRINT1("Freeing page with rmap entries.\n"); DPRINT1("Freeing page with rmap entries.\n");
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -636,7 +633,7 @@ NTAPI
MmGetLockCountPage(PFN_TYPE Pfn) MmGetLockCountPage(PFN_TYPE Pfn)
{ {
KIRQL oldIrql; KIRQL oldIrql;
ULONG LockCount; ULONG CurrentLockCount;
PPHYSICAL_PAGE Page; PPHYSICAL_PAGE Page;
DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
@ -650,10 +647,10 @@ MmGetLockCountPage(PFN_TYPE Pfn)
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
LockCount = Page->LockCount; CurrentLockCount = Page->LockCount;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(LockCount); return(CurrentLockCount);
} }
VOID VOID
@ -711,7 +708,7 @@ MmUnlockPage(PFN_TYPE Pfn)
PFN_TYPE PFN_TYPE
NTAPI NTAPI
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry) MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
{ {
PFN_TYPE PfnOffset; PFN_TYPE PfnOffset;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
@ -774,7 +771,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
PageDescriptor->ReferenceCount = 1; PageDescriptor->ReferenceCount = 1;
PageDescriptor->LockCount = 0; PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0; PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = SavedSwapEntry; PageDescriptor->SavedSwapEntry = SwapEntry;
MmStats.NrSystemPages++; MmStats.NrSystemPages++;
MmStats.NrFreePages--; MmStats.NrFreePages--;

View file

@ -403,7 +403,7 @@ MmInit1(VOID)
/* We'll put the PFN array right after the loaded modules */ /* We'll put the PFN array right after the loaded modules */
MmPfnDatabase = (PVOID)MiKSeg0End; MmPfnDatabase = (PVOID)MiKSeg0End;
MmPfnDatabaseEnd = (ULONG_PTR)MmPfnDatabase + (MmHighestPhysicalPage * sizeof(PHYSICAL_PAGE)); MmPfnDatabaseEnd = (ULONG_PTR)MmPfnDatabase + (MmHighestPhysicalPage * sizeof(MMPFN));
MmPfnDatabaseEnd = PAGE_ROUND_UP(MmPfnDatabaseEnd); MmPfnDatabaseEnd = PAGE_ROUND_UP(MmPfnDatabaseEnd);
/* /*