[NTOS:Mm] Use MmRebalanceMemoryConsumersAndWait in the page fault handler

This commit is contained in:
Timo Kreuzer 2023-04-05 23:02:43 +03:00
parent 047dc9729f
commit 876769fdd5
2 changed files with 34 additions and 3 deletions

View file

@ -15,6 +15,10 @@
#define MODULE_INVOLVED_IN_ARM3
#include <mm/ARM3/miarm.h>
VOID
NTAPI
MmRebalanceMemoryConsumersAndWait(VOID);
/* GLOBALS ********************************************************************/
#define HYDRA_PROCESS (PEPROCESS)1
@ -1940,7 +1944,7 @@ _WARN("Session space stuff is not implemented yet!")
return STATUS_IN_PAGE_ERROR | 0x10000000;
}
}
RetryKernel:
/* Acquire the working set lock */
KeRaiseIrql(APC_LEVEL, &LockIrql);
MiLockWorkingSet(CurrentThread, WorkingSet);
@ -2107,6 +2111,12 @@ _WARN("Session space stuff is not implemented yet!")
MiUnlockWorkingSet(CurrentThread, WorkingSet);
KeLowerIrql(LockIrql);
if (Status == STATUS_NO_MEMORY)
{
MmRebalanceMemoryConsumersAndWait();
goto RetryKernel;
}
/* We are done! */
DPRINT("Fault resolved with status: %lx\n", Status);
return Status;
@ -2616,6 +2626,13 @@ ExitUser:
/* Return the status */
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
if (Status == STATUS_NO_MEMORY)
{
MmRebalanceMemoryConsumersAndWait();
goto UserFault;
}
return Status;
}

View file

@ -200,6 +200,10 @@ MmNotPresentFault(KPROCESSOR_MODE Mode,
extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
VOID
NTAPI
MmRebalanceMemoryConsumersAndWait(VOID);
NTSTATUS
NTAPI
MmAccessFault(IN ULONG FaultCode,
@ -208,6 +212,7 @@ MmAccessFault(IN ULONG FaultCode,
IN PVOID TrapInformation)
{
PMEMORY_AREA MemoryArea = NULL;
NTSTATUS Status;
/* Cute little hack for ROS */
if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)
@ -252,16 +257,25 @@ MmAccessFault(IN ULONG FaultCode,
return MmArmAccessFault(FaultCode, Address, Mode, TrapInformation);
}
Retry:
/* Keep same old ReactOS Behaviour */
if (!MI_IS_NOT_PRESENT_FAULT(FaultCode))
{
/* Call access fault */
return MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
Status = MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
}
else
{
/* Call not present */
return MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
Status = MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
}
if (Status == STATUS_NO_MEMORY)
{
MmRebalanceMemoryConsumersAndWait();
goto Retry;
}
return Status;
}