mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 23:18:39 +00:00
- 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:
parent
66a0e71bf5
commit
4fbc4ba227
4 changed files with 99 additions and 74 deletions
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue