mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 04:33:32 +00:00
[NTOSKRNL/MM]
- Stop leaking references to PDEs. Still one reference left to the TLB mapping at process deletion. svn path=/trunk/; revision=55763
This commit is contained in:
parent
30703d5a5d
commit
d720941f1e
5 changed files with 181 additions and 22 deletions
|
@ -113,6 +113,12 @@ MmPageOutVirtualMemory(PMMSUPPORT AddressSpace,
|
||||||
MmCreatePageFileMapping(Process, Address, SwapEntry);
|
MmCreatePageFileMapping(Process, Address, SwapEntry);
|
||||||
MmSetSavedSwapEntryPage(Page, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
}
|
}
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
else if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
MmReleasePageMemoryConsumer(MC_USER, Page);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
@ -191,6 +197,9 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
|
||||||
PMM_REGION Region;
|
PMM_REGION Region;
|
||||||
PMM_PAGEOP PageOp;
|
PMM_PAGEOP PageOp;
|
||||||
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
|
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
BOOLEAN refPde = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is a window between taking the page fault and locking the
|
* There is a window between taking the page fault and locking the
|
||||||
|
@ -326,7 +335,17 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
|
||||||
KeBugCheck(MEMORY_MANAGEMENT);
|
KeBugCheck(MEMORY_MANAGEMENT);
|
||||||
}
|
}
|
||||||
MmSetSavedSwapEntryPage(Page, SwapEntry);
|
MmSetSavedSwapEntryPage(Page, SwapEntry);
|
||||||
|
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* PTE was already "created", no need to reference PDE */
|
||||||
|
refPde = FALSE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Add an additional page table reference */
|
||||||
|
if(refPde) MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] <= PTE_COUNT);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the page. If we fail because we are out of memory then
|
* Set the page. If we fail because we are out of memory then
|
||||||
|
@ -337,16 +356,6 @@ MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
&Page,
|
&Page,
|
||||||
1);
|
1);
|
||||||
while (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(Process,
|
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
|
||||||
Region->Protect,
|
|
||||||
&Page,
|
|
||||||
1);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
|
DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
@ -393,9 +402,9 @@ MmModifyAttributes(PMMSUPPORT AddressSpace,
|
||||||
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
|
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
PFN_NUMBER Page;
|
PFN_NUMBER Page;
|
||||||
|
PVOID Address = (char*)BaseAddress + (i*PAGE_SIZE);
|
||||||
|
|
||||||
if (MmIsPageSwapEntry(Process,
|
if (MmIsPageSwapEntry(Process, Address))
|
||||||
(char*)BaseAddress + (i * PAGE_SIZE)))
|
|
||||||
{
|
{
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
|
|
||||||
|
@ -403,11 +412,17 @@ MmModifyAttributes(PMMSUPPORT AddressSpace,
|
||||||
(char*)BaseAddress + (i * PAGE_SIZE),
|
(char*)BaseAddress + (i * PAGE_SIZE),
|
||||||
&SwapEntry);
|
&SwapEntry);
|
||||||
MmFreeSwapPage(SwapEntry);
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmDeleteVirtualMapping(Process,
|
MmDeleteVirtualMapping(Process,
|
||||||
(char*)BaseAddress + (i*PAGE_SIZE),
|
Address,
|
||||||
FALSE, NULL, &Page);
|
FALSE, NULL, &Page);
|
||||||
if (Page != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
|
@ -421,6 +436,12 @@ MmModifyAttributes(PMMSUPPORT AddressSpace,
|
||||||
MmDeleteRmap(Page, Process,
|
MmDeleteRmap(Page, Process,
|
||||||
(char*)BaseAddress + (i * PAGE_SIZE));
|
(char*)BaseAddress + (i * PAGE_SIZE));
|
||||||
MmReleasePageMemoryConsumer(MC_USER, Page);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "ARM3/miarm.h"
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
#if defined (ALLOC_PRAGMA)
|
||||||
#pragma alloc_text(INIT, MmInitializeBalancer)
|
#pragma alloc_text(INIT, MmInitializeBalancer)
|
||||||
#pragma alloc_text(INIT, MmInitializeMemoryConsumer)
|
#pragma alloc_text(INIT, MmInitializeMemoryConsumer)
|
||||||
|
@ -232,10 +234,40 @@ MiIsBalancerThread(VOID)
|
||||||
(PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
|
(PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiDeletePte(IN PMMPTE PointerPte,
|
||||||
|
IN PVOID VirtualAddress,
|
||||||
|
IN PEPROCESS CurrentProcess,
|
||||||
|
IN PMMPTE PrototypePte);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmRebalanceMemoryConsumers(VOID)
|
MmRebalanceMemoryConsumers(VOID)
|
||||||
{
|
{
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
if(!MiIsBalancerThread())
|
||||||
|
{
|
||||||
|
/* Clean up the unused PDEs */
|
||||||
|
ULONG_PTR Address;
|
||||||
|
KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
PMMPDE pointerPde;
|
||||||
|
for(Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS;
|
||||||
|
Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;
|
||||||
|
Address += (PAGE_SIZE * PTE_COUNT))
|
||||||
|
{
|
||||||
|
if(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] == 0)
|
||||||
|
{
|
||||||
|
pointerPde = MiAddressToPde(Address);
|
||||||
|
if(pointerPde->u.Hard.Valid)
|
||||||
|
MiDeletePte(pointerPde, MiPdeToPte(pointerPde), PsGetCurrentProcess(), NULL);
|
||||||
|
ASSERT(pointerPde->u.Hard.Valid == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (MiBalancerThreadHandle != NULL &&
|
if (MiBalancerThreadHandle != NULL &&
|
||||||
!MiIsBalancerThread())
|
!MiIsBalancerThread())
|
||||||
{
|
{
|
||||||
|
|
|
@ -258,9 +258,22 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
|
||||||
{
|
{
|
||||||
/* Nobody but page fault should ask for creating the PDE,
|
/* Nobody but page fault should ask for creating the PDE,
|
||||||
* Which imples that Process is the current one */
|
* Which imples that Process is the current one */
|
||||||
ASSERT(Create == FALSE);
|
|
||||||
MmDeleteHyperspaceMapping(PdeBase);
|
MmDeleteHyperspaceMapping(PdeBase);
|
||||||
return NULL;
|
if(Create == FALSE)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
PULONG ret;
|
||||||
|
/* Attach to process */
|
||||||
|
KeStackAttachProcess(&Process->Pcb, &ApcState);
|
||||||
|
|
||||||
|
/* Retry */
|
||||||
|
ret = MmGetPageTableForProcess(Process, Address, TRUE);
|
||||||
|
|
||||||
|
/* Get Back to original process */
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -293,6 +306,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is for kernel land address */
|
/* This is for kernel land address */
|
||||||
|
ASSERT(Process == NULL);
|
||||||
PointerPde = MiAddressToPde(Address);
|
PointerPde = MiAddressToPde(Address);
|
||||||
Pt = (PULONG)MiAddressToPte(Address);
|
Pt = (PULONG)MiAddressToPte(Address);
|
||||||
if (PointerPde->u.Hard.Valid == 0)
|
if (PointerPde->u.Hard.Valid == 0)
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "ARM3/miarm.h"
|
||||||
|
|
||||||
MEMORY_AREA MiStaticMemoryAreas[MI_STATIC_MEMORY_AREAS];
|
MEMORY_AREA MiStaticMemoryAreas[MI_STATIC_MEMORY_AREAS];
|
||||||
ULONG MiStaticMemoryAreaCount;
|
ULONG MiStaticMemoryAreaCount;
|
||||||
|
|
||||||
|
@ -688,6 +690,12 @@ IN PMM_AVL_TABLE Table);
|
||||||
*
|
*
|
||||||
* @remarks Lock the address space before calling this function.
|
* @remarks Lock the address space before calling this function.
|
||||||
*/
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiDeletePte(IN PMMPTE PointerPte,
|
||||||
|
IN PVOID VirtualAddress,
|
||||||
|
IN PEPROCESS CurrentProcess,
|
||||||
|
IN PMMPTE PrototypePte);
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
MmFreeMemoryArea(
|
MmFreeMemoryArea(
|
||||||
|
@ -716,9 +724,9 @@ MmFreeMemoryArea(
|
||||||
Address < (ULONG_PTR)EndAddress;
|
Address < (ULONG_PTR)EndAddress;
|
||||||
Address += PAGE_SIZE)
|
Address += PAGE_SIZE)
|
||||||
{
|
{
|
||||||
BOOLEAN Dirty = FALSE;
|
BOOLEAN Dirty = FALSE;
|
||||||
SWAPENTRY SwapEntry = 0;
|
SWAPENTRY SwapEntry = 0;
|
||||||
PFN_NUMBER Page = 0;
|
PFN_NUMBER Page = 0;
|
||||||
|
|
||||||
if (MmIsPageSwapEntry(Process, (PVOID)Address))
|
if (MmIsPageSwapEntry(Process, (PVOID)Address))
|
||||||
{
|
{
|
||||||
|
@ -733,6 +741,25 @@ MmFreeMemoryArea(
|
||||||
FreePage(FreePageContext, MemoryArea, (PVOID)Address,
|
FreePage(FreePageContext, MemoryArea, (PVOID)Address,
|
||||||
Page, SwapEntry, (BOOLEAN)Dirty);
|
Page, SwapEntry, (BOOLEAN)Dirty);
|
||||||
}
|
}
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Remove page table reference */
|
||||||
|
if((SwapEntry || Page) && ((PVOID)Address < MmSystemRangeStart))
|
||||||
|
{
|
||||||
|
ASSERT(AddressSpace != MmGetKernelAddressSpace());
|
||||||
|
MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
|
||||||
|
ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_COUNT);
|
||||||
|
if(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] == 0)
|
||||||
|
{
|
||||||
|
/* No PTE relies on this PDE. Release it */
|
||||||
|
KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
PMMPDE PointerPde = MiAddressToPde(Address);
|
||||||
|
ASSERT(PointerPde->u.Hard.Valid == 1);
|
||||||
|
MiDeletePte(PointerPde, MiPdeToPte(PointerPde), Process, NULL);
|
||||||
|
ASSERT(PointerPde->u.Hard.Valid == 0);
|
||||||
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Process != NULL &&
|
if (Process != NULL &&
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#pragma alloc_text(INIT, MmInitSectionImplementation)
|
#pragma alloc_text(INIT, MmInitSectionImplementation)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "ARM3/miarm.h"
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiMapViewInSystemSpace(IN PVOID Section,
|
MiMapViewInSystemSpace(IN PVOID Section,
|
||||||
|
@ -1449,6 +1451,15 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
||||||
|
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset);
|
MmSharePageEntrySectionSegment(Segment, Offset);
|
||||||
|
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Reference Page Directory Entry */
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] <= PTE_COUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* FIXME: Should we call MmCreateVirtualMappingUnsafe if
|
/* FIXME: Should we call MmCreateVirtualMappingUnsafe if
|
||||||
* (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
|
* (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
|
||||||
*/
|
*/
|
||||||
|
@ -1538,6 +1549,15 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Reference Page Directory Entry */
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] <= PTE_COUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Satisfying a page fault on a map of /Device/PhysicalMemory is easy
|
* Satisfying a page fault on a map of /Device/PhysicalMemory is easy
|
||||||
*/
|
*/
|
||||||
|
@ -1658,6 +1678,12 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Cleanup and release locks
|
* Cleanup and release locks
|
||||||
*/
|
*/
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
PageOp->Status = Status;
|
PageOp->Status = Status;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
|
@ -1877,6 +1903,9 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(OldPage == 0)
|
||||||
|
DPRINT("OldPage == 0!\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get or create a pageop
|
* Get or create a pageop
|
||||||
*/
|
*/
|
||||||
|
@ -2022,6 +2051,14 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
MmReleasePageMemoryConsumer(MC_USER, Page);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
if(Process->VmDeleted) DPRINT1("deleted!!!");
|
||||||
|
Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
DPRINT("PhysicalAddress %x, Address %x\n", Page << PAGE_SHIFT, Address);
|
DPRINT("PhysicalAddress %x, Address %x\n", Page << PAGE_SHIFT, Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2254,6 +2291,13 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
|
||||||
{
|
{
|
||||||
MmSetSavedSwapEntryPage(Page, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Page table was dereferenced while deleting the RMAP */
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Status = MmCreatePageFileMapping(Process,
|
Status = MmCreatePageFileMapping(Process,
|
||||||
Address,
|
Address,
|
||||||
SwapEntry);
|
SwapEntry);
|
||||||
|
@ -2281,6 +2325,13 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
|
||||||
/*
|
/*
|
||||||
* For private pages restore the old mappings.
|
* For private pages restore the old mappings.
|
||||||
*/
|
*/
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Page table was dereferenced while deleting the RMAP */
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
{
|
{
|
||||||
Status = MmCreateVirtualMapping(Process,
|
Status = MmCreateVirtualMapping(Process,
|
||||||
|
@ -2331,6 +2382,13 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
|
||||||
* As above: undo our actions.
|
* As above: undo our actions.
|
||||||
* FIXME: Also free the swap page.
|
* FIXME: Also free the swap page.
|
||||||
*/
|
*/
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Page table was dereferenced while deleting the RMAP */
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
{
|
{
|
||||||
|
@ -2382,6 +2440,13 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
{
|
{
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
/* Page table was dereferenced while deleting the RMAP */
|
||||||
|
if(Address < MmSystemRangeStart)
|
||||||
|
{
|
||||||
|
AddressSpace->VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Status = MmCreatePageFileMapping(Process,
|
Status = MmCreatePageFileMapping(Process,
|
||||||
Address,
|
Address,
|
||||||
SwapEntry);
|
SwapEntry);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue