https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a5fd8f48795ab1819484b...
commit 6a5fd8f48795ab1819484b433194ee9357eb8bf1 Author: Jérôme Gardou jerome.gardou@reactos.org AuthorDate: Tue May 11 12:03:52 2021 +0200 Commit: Jérôme Gardou zefklop@users.noreply.github.com CommitDate: Tue May 18 23:42:19 2021 +0200
[NTOS:MM] Relax requirements with regards to PFN lock when adding & removing entries in Working Sets
Once a page is used, holding the WS lock is enough until you want to free it. --- ntoskrnl/mm/ARM3/miarm.h | 9 ++++++ ntoskrnl/mm/ARM3/procsup.c | 6 ++-- ntoskrnl/mm/ARM3/wslist.cpp | 79 +++++++++++++++++++++++++-------------------- 3 files changed, 56 insertions(+), 38 deletions(-)
diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index adb6af3fd91..730acdd8bf1 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -1052,6 +1052,15 @@ MM_ANY_WS_LOCK_HELD(IN PETHREAD Thread) (Thread->OwnsSessionWorkingSetShared)); }
+FORCEINLINE +BOOLEAN +MM_ANY_WS_LOCK_HELD_EXCLUSIVE(_In_ PETHREAD Thread) +{ + return ((Thread->OwnsProcessWorkingSetExclusive) || + (Thread->OwnsSystemWorkingSetExclusive) || + (Thread->OwnsSessionWorkingSetExclusive)); +} + // // Checks if the process owns the working set lock // diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c index aa9133b1929..5f24a8a0b95 100644 --- a/ntoskrnl/mm/ARM3/procsup.c +++ b/ntoskrnl/mm/ARM3/procsup.c @@ -993,6 +993,9 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process, PageFrameNumber = PFN_FROM_PTE(PointerPte); MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
+ /* All our pages are now active & valid. Release the lock. */ + MiReleasePfnLock(OldIrql); + /* This should be in hyper space, but not in the mapping range */ Process->Vm.VmWorkingSetList = MmWorkingSetList; ASSERT(((ULONG_PTR)MmWorkingSetList >= MI_MAPPING_RANGE_END) && ((ULONG_PTR)MmWorkingSetList <= HYPER_SPACE_END)); @@ -1016,9 +1019,6 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process, /* Sanity check */ ASSERT(Process->PhysicalVadRoot == NULL);
- /* Release PFN lock */ - MiReleasePfnLock(OldIrql); - /* Release the process working set */ MiUnlockProcessWorkingSet(Process, PsGetCurrentThread()); #ifdef _M_AMD64 diff --git a/ntoskrnl/mm/ARM3/wslist.cpp b/ntoskrnl/mm/ARM3/wslist.cpp index 430e2c1a564..91cd87b354f 100644 --- a/ntoskrnl/mm/ARM3/wslist.cpp +++ b/ntoskrnl/mm/ARM3/wslist.cpp @@ -84,11 +84,15 @@ static void FreeWsleIndex(PMMWSL WsList, ULONG Index) ASSERT(MiPteToAddress(PointerPte) != WsList);
PFN_NUMBER Page = PFN_FROM_PTE(PointerPte); - PMMPFN Pfn = MiGetPfnEntry(Page);
- MI_SET_PFN_DELETED(Pfn); - MiDecrementShareCount(MiGetPfnEntry(Pfn->u4.PteFrame), Pfn->u4.PteFrame); - MiDecrementShareCount(Pfn, Page); + { + MiPfnLockGuard PfnLock; + + PMMPFN Pfn = MiGetPfnEntry(Page); + MI_SET_PFN_DELETED(Pfn); + MiDecrementShareCount(MiGetPfnEntry(Pfn->u4.PteFrame), Pfn->u4.PteFrame); + MiDecrementShareCount(Pfn, Page); + }
PointerPte->u.Long = 0;
@@ -172,8 +176,13 @@ static ULONG GetFreeWsleIndex(PMMWSL WsList) PMMPTE PointerPte = MiAddressToPte(&WsList->Wsle[WsList->LastInitializedWsle]); ASSERT(PointerPte->u.Hard.Valid == 0); MMPTE TempPte = GetPteTemplateForWsList(WsList); - TempPte.u.Hard.PageFrameNumber = MiRemoveAnyPage(GetNextPageColorForWsList(WsList)); - MiInitializePfnAndMakePteValid(TempPte.u.Hard.PageFrameNumber, PointerPte, TempPte); + { + MiPfnLockGuard PfnLock; + + TempPte.u.Hard.PageFrameNumber = MiRemoveAnyPage(GetNextPageColorForWsList(WsList)); + MiInitializePfnAndMakePteValid(TempPte.u.Hard.PageFrameNumber, PointerPte, TempPte); + } + WsList->LastInitializedWsle += PAGE_SIZE / sizeof(MMWSLE); } } @@ -187,8 +196,7 @@ VOID RemoveFromWsList(PMMWSL WsList, PVOID Address) { /* Make sure that we are holding the right locks. */ - ASSERT(MM_ANY_WS_LOCK_HELD(PsGetCurrentThread())); - MI_ASSERT_PFN_LOCK_HELD(); + ASSERT(MM_ANY_WS_LOCK_HELD_EXCLUSIVE(PsGetCurrentThread()));
PMMPTE PointerPte = MiAddressToPte(Address);
@@ -262,37 +270,37 @@ TrimWsList(PMMWSL WsList)
/* Please put yourself aside and make place for the younger ones */ PFN_NUMBER Page = PFN_FROM_PTE(PointerPte); - KIRQL OldIrql = MiAcquirePfnLock(); + { + MiPfnLockGuard PfnLock;
- PMMPFN Pfn = MiGetPfnEntry(Page); + PMMPFN Pfn = MiGetPfnEntry(Page);
- /* Not supported yet */ - ASSERT(Pfn->u3.e1.PrototypePte == 0); - ASSERT(!MI_IS_ROS_PFN(Pfn)); + /* Not supported yet */ + ASSERT(Pfn->u3.e1.PrototypePte == 0); + ASSERT(!MI_IS_ROS_PFN(Pfn));
- /* FIXME: Remove this hack when possible */ - if (Pfn->Wsle.u1.e1.LockedInMemory || (Pfn->Wsle.u1.e1.LockedInWs)) - { - MiReleasePfnLock(OldIrql); - continue; - } + /* FIXME: Remove this hack when possible */ + if (Pfn->Wsle.u1.e1.LockedInMemory || (Pfn->Wsle.u1.e1.LockedInWs)) + { + continue; + }
- /* We can remove it from the list. Save Protection first */ - ULONG Protection = Entry.u1.e1.Protection; - RemoveFromWsList(WsList, Entry.u1.VirtualAddress); + /* We can remove it from the list. Save Protection first */ + ULONG Protection = Entry.u1.e1.Protection; + RemoveFromWsList(WsList, Entry.u1.VirtualAddress);
- /* Dirtify the page, if needed */ - if (PointerPte->u.Hard.Dirty) - Pfn->u3.e1.Modified = 1; + /* Dirtify the page, if needed */ + if (PointerPte->u.Hard.Dirty) + Pfn->u3.e1.Modified = 1;
- /* Make this a transition PTE */ - MI_MAKE_TRANSITION_PTE(PointerPte, Page, Protection); - KeInvalidateTlbEntry(MiAddressToPte(PointerPte)); + /* Make this a transition PTE */ + MI_MAKE_TRANSITION_PTE(PointerPte, Page, Protection); + KeInvalidateTlbEntry(MiAddressToPte(PointerPte));
- /* Drop the share count. This will take care of putting it in the standby or modified list. */ - MiDecrementShareCount(Pfn, Page); + /* Drop the share count. This will take care of putting it in the standby or modified list. */ + MiDecrementShareCount(Pfn, Page); + }
- MiReleasePfnLock(OldIrql); Ret++; } return Ret; @@ -302,6 +310,7 @@ TrimWsList(PMMWSL WsList) extern "C" {
+_Use_decl_annotations_ VOID NTAPI MiInsertInWorkingSetList( @@ -311,9 +320,8 @@ MiInsertInWorkingSetList( { PMMWSL WsList = Vm->VmWorkingSetList;
- /* Make sure that we are holding the right locks. */ - ASSERT(MM_ANY_WS_LOCK_HELD(PsGetCurrentThread())); - MI_ASSERT_PFN_LOCK_HELD(); + /* Make sure that we are holding the WS lock. */ + ASSERT(MM_ANY_WS_LOCK_HELD_EXCLUSIVE(PsGetCurrentThread()));
PMMPTE PointerPte = MiAddressToPte(Address);
@@ -345,6 +353,7 @@ MiInsertInWorkingSetList( Vm->PeakWorkingSetSize = Vm->WorkingSetSize; }
+_Use_decl_annotations_ VOID NTAPI MiRemoveFromWorkingSetList( @@ -356,7 +365,7 @@ MiRemoveFromWorkingSetList( Vm->WorkingSetSize -= PAGE_SIZE; }
-_Requires_exclusive_lock_held_(WorkingSet->WorkingSetMutex) +_Use_decl_annotations_ VOID NTAPI MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet)