- 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;
} 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
{
struct
{
ULONG Type: 2;
ULONG Consumer: 3;
ULONG Zero: 1;
ULONG StartOfAllocation: 1;
ULONG EndOfAllocation: 1;
}
Flags;
ULONG AllFlags;
USHORT ReferenceCount; // ReferenceCount
MMPFNENTRY e1;
};
struct
{
USHORT ReferenceCount;
USHORT ShortFlags;
} e2;
} u3;
union
{
MMPTE OriginalPte;
LONG AweReferenceCount; // RmapListHead
};
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
SWAPENTRY SavedSwapEntry;
ULONG LockCount;
ULONG MapCount;
struct _MM_RMAP_ENTRY* RmapListHead;
}
PHYSICAL_PAGE, *PPHYSICAL_PAGE;
union
{
ULONG_PTR EntireFrame; // SavedSwapEntry
struct
{
ULONG_PTR PteFrame:25;
ULONG_PTR InPageError:1;
ULONG_PTR VerifierAllocation:1;
ULONG_PTR AweAllocation:1;
ULONG_PTR Priority:3;
ULONG_PTR MustBeCached:1;
};
} u4;
} MMPFN, *PMMPFN;
extern MM_STATS MmStats;
@ -991,14 +1029,14 @@ MmPageOutPhysicalAddress(PFN_TYPE Page);
/* freelist.c **********************************************************/
#define ASSERT_PFN(x) ASSERT((x)->Flags.Type != 0)
#define ASSERT_PFN(x) ASSERT((x)->u3.e1.CacheAttribute != 0)
FORCEINLINE
PPHYSICAL_PAGE
PMMPFN
MiGetPfnEntry(IN PFN_TYPE Pfn)
{
PPHYSICAL_PAGE Page;
extern PPHYSICAL_PAGE MmPageArray;
PMMPFN Page;
extern PMMPFN MmPageArray;
extern ULONG MmPageArraySize;
/* Mark MmPageArraySize as unreferenced, otherwise it will appear as an unused variable on a Release build */
@ -1278,16 +1316,6 @@ BOOLEAN
NTAPI
MmIsPageInUse(PFN_TYPE Page);
VOID
NTAPI
MmSetFlagsPage(
PFN_TYPE Page,
ULONG Flags);
ULONG
NTAPI
MmGetFlagsPage(PFN_TYPE Page);
VOID
NTAPI
MmSetSavedSwapEntryPage(

View file

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

View file

@ -27,6 +27,27 @@
/* 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;
ULONG MmPageArraySize;
@ -94,7 +115,7 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn)
Page = MiGetPfnEntry(PreviousPfn);
ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED);
ASSERT(Page->Flags.Consumer == MC_USER);
NextListEntry = Page->ListEntry.Flink;
NextListEntry = (PLIST_ENTRY)Page->ListEntry.Flink;
if (NextListEntry == &UserPageListHead)
{
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
@ -295,10 +316,12 @@ MmInitializePageList(VOID)
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
NextEntry = NextEntry->Flink)
{
#undef ListEntry
/* Get the descriptor */
Md = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
#define ListEntry u1
/* Skip bad memory */
if ((Md->MemoryType == LoaderFirmwarePermanent) ||
@ -366,17 +389,6 @@ MmInitializePageList(VOID)
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
NTAPI
MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead)
@ -384,7 +396,7 @@ MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead)
KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiGetPfnEntry(Pfn)->RmapListHead = ListHead;
MiGetPfnEntry(Pfn)->RmapListHead = (LONG)ListHead;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
@ -396,7 +408,7 @@ MmGetRmapListHeadPage(PFN_TYPE Pfn)
struct _MM_RMAP_ENTRY* ListHead;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
ListHead = MiGetPfnEntry(Pfn)->RmapListHead;
ListHead = (struct _MM_RMAP_ENTRY*)MiGetPfnEntry(Pfn)->RmapListHead;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
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
NTAPI
MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SavedSwapEntry)
MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SwapEntry)
{
KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiGetPfnEntry(Pfn)->SavedSwapEntry = SavedSwapEntry;
MiGetPfnEntry(Pfn)->SavedSwapEntry = SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
@ -481,14 +478,14 @@ SWAPENTRY
NTAPI
MmGetSavedSwapEntryPage(PFN_TYPE Pfn)
{
SWAPENTRY SavedSwapEntry;
SWAPENTRY SwapEntry;
KIRQL oldIrql;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
SavedSwapEntry = MiGetPfnEntry(Pfn)->SavedSwapEntry;
SwapEntry = MiGetPfnEntry(Pfn)->SavedSwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(SavedSwapEntry);
return(SwapEntry);
}
VOID
@ -591,7 +588,7 @@ MmDereferencePage(PFN_TYPE Pfn)
MmStats.NrFreePages++;
MmStats.NrSystemPages--;
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");
KeBugCheck(MEMORY_MANAGEMENT);
@ -636,7 +633,7 @@ NTAPI
MmGetLockCountPage(PFN_TYPE Pfn)
{
KIRQL oldIrql;
ULONG LockCount;
ULONG CurrentLockCount;
PPHYSICAL_PAGE Page;
DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
@ -650,10 +647,10 @@ MmGetLockCountPage(PFN_TYPE Pfn)
KeBugCheck(MEMORY_MANAGEMENT);
}
LockCount = Page->LockCount;
CurrentLockCount = Page->LockCount;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(LockCount);
return(CurrentLockCount);
}
VOID
@ -711,7 +708,7 @@ MmUnlockPage(PFN_TYPE Pfn)
PFN_TYPE
NTAPI
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
MmAllocPage(ULONG Consumer, SWAPENTRY SwapEntry)
{
PFN_TYPE PfnOffset;
PLIST_ENTRY ListEntry;
@ -774,7 +771,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
PageDescriptor->ReferenceCount = 1;
PageDescriptor->LockCount = 0;
PageDescriptor->MapCount = 0;
PageDescriptor->SavedSwapEntry = SavedSwapEntry;
PageDescriptor->SavedSwapEntry = SwapEntry;
MmStats.NrSystemPages++;
MmStats.NrFreePages--;

View file

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