mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 12:24:48 +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;
|
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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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--;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue