mirror of
https://github.com/reactos/reactos.git
synced 2025-03-30 17:10:22 +00:00
[NTOS:MM] Make MiCalculatePageCommitment 64-bits aware
This commit is contained in:
parent
b48e27ada1
commit
a80ae8f2ea
1 changed files with 106 additions and 128 deletions
|
@ -46,157 +46,135 @@ MiCalculatePageCommitment(IN ULONG_PTR StartingAddress,
|
||||||
{
|
{
|
||||||
PMMPTE PointerPte, LastPte;
|
PMMPTE PointerPte, LastPte;
|
||||||
PMMPDE PointerPde;
|
PMMPDE PointerPde;
|
||||||
ULONG CommittedPages;
|
BOOLEAN OnPdeBoundary = TRUE;
|
||||||
|
#if _MI_PAGING_LEVELS >= 3
|
||||||
|
PMMPPE PointerPpe;
|
||||||
|
BOOLEAN OnPpeBoundary = TRUE;
|
||||||
|
#if _MI_PAGING_LEVELS == 4
|
||||||
|
PMMPXE PointerPxe;
|
||||||
|
BOOLEAN OnPxeBoundary = TRUE;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Compute starting and ending PTE and PDE addresses */
|
/* Make sure this all makes sense */
|
||||||
PointerPde = MiAddressToPde(StartingAddress);
|
ASSERT(PsGetCurrentThread()->OwnsProcessWorkingSetExclusive || PsGetCurrentThread()->OwnsProcessWorkingSetShared);
|
||||||
|
ASSERT(EndingAddress >= StartingAddress);
|
||||||
PointerPte = MiAddressToPte(StartingAddress);
|
PointerPte = MiAddressToPte(StartingAddress);
|
||||||
LastPte = MiAddressToPte(EndingAddress);
|
LastPte = MiAddressToPte(EndingAddress);
|
||||||
|
|
||||||
/* Handle commited pages first */
|
/*
|
||||||
if (Vad->u.VadFlags.MemCommit == 1)
|
* In case this is a committed VAD, assume the whole range is committed
|
||||||
{
|
* and count the individually decommitted pages.
|
||||||
/* This is a committed VAD, so Assume the whole range is committed */
|
* In case it is not, assume the range is not committed and count the individually committed pages.
|
||||||
CommittedPages = (ULONG)BYTES_TO_PAGES(EndingAddress - StartingAddress);
|
*/
|
||||||
|
ULONG_PTR CommittedPages = Vad->u.VadFlags.MemCommit ? BYTES_TO_PAGES(EndingAddress - StartingAddress) : 0;
|
||||||
|
|
||||||
/* Is the PDE demand-zero? */
|
|
||||||
PointerPde = MiPteToPde(PointerPte);
|
|
||||||
if (PointerPde->u.Long != 0)
|
|
||||||
{
|
|
||||||
/* It is not. Is it valid? */
|
|
||||||
if (PointerPde->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
/* Fault it in */
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
MiMakeSystemAddressValid(PointerPte, Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is, skip it and move to the next PDE, unless we're done */
|
|
||||||
PointerPde++;
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
if (PointerPte > LastPte) return CommittedPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now loop all the PTEs in the range */
|
|
||||||
while (PointerPte <= LastPte)
|
|
||||||
{
|
|
||||||
/* Have we crossed a PDE boundary? */
|
|
||||||
if (MiIsPteOnPdeBoundary(PointerPte))
|
|
||||||
{
|
|
||||||
/* Is this PDE demand zero? */
|
|
||||||
PointerPde = MiPteToPde(PointerPte);
|
|
||||||
if (PointerPde->u.Long != 0)
|
|
||||||
{
|
|
||||||
/* It isn't -- is it valid? */
|
|
||||||
if (PointerPde->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
/* Nope, fault it in */
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
MiMakeSystemAddressValid(PointerPte, Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is, skip it and move to the next PDE */
|
|
||||||
PointerPde++;
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this PTE demand zero? */
|
|
||||||
if (PointerPte->u.Long != 0)
|
|
||||||
{
|
|
||||||
/* It isn't -- is it a decommited, invalid, or faulted PTE? */
|
|
||||||
if ((PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
|
|
||||||
(PointerPte->u.Hard.Valid == 0) &&
|
|
||||||
((PointerPte->u.Soft.Prototype == 0) ||
|
|
||||||
(PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
|
|
||||||
{
|
|
||||||
/* It is, so remove it from the count of commited pages */
|
|
||||||
CommittedPages--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next PTE */
|
|
||||||
PointerPte++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return how many committed pages there still are */
|
|
||||||
return CommittedPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a non-commited VAD, so assume none of it is committed */
|
|
||||||
CommittedPages = 0;
|
|
||||||
|
|
||||||
/* Is the PDE demand-zero? */
|
|
||||||
PointerPde = MiPteToPde(PointerPte);
|
|
||||||
if (PointerPde->u.Long != 0)
|
|
||||||
{
|
|
||||||
/* It isn't -- is it invalid? */
|
|
||||||
if (PointerPde->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
/* It is, so page it in */
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
MiMakeSystemAddressValid(PointerPte, Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is, so skip it and move to the next PDE */
|
|
||||||
PointerPde++;
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
if (PointerPte > LastPte) return CommittedPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop all the PTEs in this PDE */
|
|
||||||
while (PointerPte <= LastPte)
|
while (PointerPte <= LastPte)
|
||||||
{
|
{
|
||||||
/* Have we crossed a PDE boundary? */
|
#if _MI_PAGING_LEVELS == 4
|
||||||
if (MiIsPteOnPdeBoundary(PointerPte))
|
/* Check if PXE was ever paged in. */
|
||||||
|
if (OnPxeBoundary)
|
||||||
{
|
{
|
||||||
/* Is this new PDE demand-zero? */
|
PointerPxe = MiPteToPxe(PointerPte);
|
||||||
PointerPde = MiPteToPde(PointerPte);
|
|
||||||
if (PointerPde->u.Long != 0)
|
/* Check that this loop is sane */
|
||||||
|
ASSERT(OnPpeBoundary);
|
||||||
|
ASSERT(OnPdeBoundary);
|
||||||
|
|
||||||
|
if (PointerPxe->u.Long == 0)
|
||||||
{
|
{
|
||||||
/* It isn't. Is it valid? */
|
PointerPxe++;
|
||||||
if (PointerPde->u.Hard.Valid == 0)
|
PointerPte = MiPxeToPte(PointerPde);
|
||||||
{
|
|
||||||
/* It isn't, so make it valid */
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
MiMakeSystemAddressValid(PointerPte, Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is, so skip it and move to the next one */
|
|
||||||
PointerPde++;
|
|
||||||
PointerPte = MiPteToAddress(PointerPde);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this PTE demand-zero? */
|
if (PointerPxe->u.Hard.Valid == 0)
|
||||||
|
MiMakeSystemAddressValid(MiPteToPpe(PointerPte), Process);
|
||||||
|
}
|
||||||
|
ASSERT(PointerPxe->u.Hard.Valid == 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _MI_PAGING_LEVELS >= 3
|
||||||
|
/* Now PPE */
|
||||||
|
if (OnPpeBoundary)
|
||||||
|
{
|
||||||
|
PointerPpe = MiPteToPpe(PointerPte);
|
||||||
|
|
||||||
|
/* Sanity again */
|
||||||
|
ASSERT(OnPdeBoundary);
|
||||||
|
|
||||||
|
if (PointerPpe->u.Long == 0)
|
||||||
|
{
|
||||||
|
PointerPpe++;
|
||||||
|
PointerPte = MiPpeToPte(PointerPpe);
|
||||||
|
#if _MI_PAGING_LEVELS == 4
|
||||||
|
OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PointerPpe->u.Hard.Valid == 0)
|
||||||
|
MiMakeSystemAddressValid(MiPteToPde(PointerPte), Process);
|
||||||
|
}
|
||||||
|
ASSERT(PointerPpe->u.Hard.Valid == 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Last level is the PDE */
|
||||||
|
if (OnPdeBoundary)
|
||||||
|
{
|
||||||
|
PointerPde = MiPteToPde(PointerPte);
|
||||||
|
if (PointerPde->u.Long == 0)
|
||||||
|
{
|
||||||
|
PointerPde++;
|
||||||
|
PointerPte = MiPdeToPte(PointerPde);
|
||||||
|
#if _MI_PAGING_LEVELS >= 3
|
||||||
|
OnPpeBoundary = MiIsPteOnPpeBoundary(PointerPte);
|
||||||
|
#if _MI_PAGING_LEVELS == 4
|
||||||
|
OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PointerPde->u.Hard.Valid == 0)
|
||||||
|
MiMakeSystemAddressValid(PointerPte, Process);
|
||||||
|
}
|
||||||
|
ASSERT(PointerPde->u.Hard.Valid == 1);
|
||||||
|
|
||||||
|
/* Is this PTE demand zero? */
|
||||||
if (PointerPte->u.Long != 0)
|
if (PointerPte->u.Long != 0)
|
||||||
{
|
{
|
||||||
/* Nope. Is it a valid, non-decommited, non-paged out PTE? */
|
/* It isn't -- is it a decommited, invalid, or faulted PTE? */
|
||||||
if ((PointerPte->u.Soft.Protection != MM_DECOMMIT) ||
|
if ((PointerPte->u.Hard.Valid == 0) &&
|
||||||
(PointerPte->u.Hard.Valid == 1) ||
|
(PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
|
||||||
((PointerPte->u.Soft.Prototype == 1) &&
|
((PointerPte->u.Soft.Prototype == 0) ||
|
||||||
(PointerPte->u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED)))
|
(PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
|
||||||
{
|
{
|
||||||
/* It is! So we'll treat this as a committed page */
|
/* It is, so remove it from the count of committed pages if we have to */
|
||||||
|
if (Vad->u.VadFlags.MemCommit)
|
||||||
|
CommittedPages--;
|
||||||
|
}
|
||||||
|
else if (!Vad->u.VadFlags.MemCommit)
|
||||||
|
{
|
||||||
|
/* It is a valid, non-decommited, non-paged out PTE. Count it in. */
|
||||||
CommittedPages++;
|
CommittedPages++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move to the next PTE */
|
/* Move to the next PTE */
|
||||||
PointerPte++;
|
PointerPte++;
|
||||||
|
/* Manage page tables */
|
||||||
|
OnPdeBoundary = MiIsPteOnPdeBoundary(PointerPte);
|
||||||
|
#if _MI_PAGING_LEVELS >= 3
|
||||||
|
OnPpeBoundary = MiIsPteOnPpeBoundary(PointerPte);
|
||||||
|
#if _MI_PAGING_LEVELS == 4
|
||||||
|
OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return how many committed pages we found in this VAD */
|
/* Make sure we didn't mess this up */
|
||||||
|
ASSERT(CommittedPages <= BYTES_TO_PAGES(EndingAddress - StartingAddress));
|
||||||
return CommittedPages;
|
return CommittedPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue