From: Jérôme Gardou Date: Mon, 25 Aug 2014 12:33:49 +0000 (+0000) Subject: [NTOS/MM] X-Git-Tag: backups/0.3.17@66124~749 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=bd074499cbe752fadaab762e6bff63e08febe65d [NTOS/MM] - Bring back PTE frame refcounting when serving a prototype PTE page fault. - Fix a bug in MiDeletePte where the said PTE frame was not unshared. - Improve transitional PTEs deletion (will be needed for future work). Do not always trust the comments stating that "strange RosMm code broke everything" svn path=/trunk/; revision=63947 --- diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index df4dbebe248..f78a445343c 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -709,12 +709,9 @@ MiCompleteProtoPteFault(IN BOOLEAN StoreInstruction, Pfn1->u3.e1.PrototypePte = 1; /* Increment the share count for the page table */ - // FIXME: This doesn't work because we seem to bump the sharecount to two, and MiDeletePte gets annoyed and ASSERTs. - // This could be beause MiDeletePte is now being called from strange code in Rosmm PageTablePte = MiAddressToPte(PointerPte); Pfn2 = MiGetPfnEntry(PageTablePte->u.Hard.PageFrameNumber); - //Pfn2->u2.ShareCount++; - DBG_UNREFERENCED_LOCAL_VARIABLE(Pfn2); + Pfn2->u2.ShareCount++; /* Check where we should be getting the protection information from */ if (PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED) diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index 932e1d04ac2..ce616018d6d 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -407,15 +407,17 @@ MiDeletePte(IN PMMPTE PointerPte, /* See if the PTE is valid */ if (TempPte.u.Hard.Valid == 0) { - /* Prototype PTEs not supported yet */ + /* Prototype and paged out PTEs not supported yet */ ASSERT(TempPte.u.Soft.Prototype == 0); + ASSERT(TempPte.u.Soft.PageFileHigh == 0); + if (TempPte.u.Soft.Transition) { /* Get the PFN entry */ PageFrameIndex = PFN_FROM_PTE(&TempPte); Pfn1 = MiGetPfnEntry(PageFrameIndex); - DPRINT1("Pte %p is transitional!\n", PointerPte); + DPRINT("Pte %p is transitional!\n", PointerPte); /* Destroy the PTE */ MI_ERASE_PTE(PointerPte); @@ -433,12 +435,14 @@ MiDeletePte(IN PMMPTE PointerPte, /* And it should be in standby or modified list */ ASSERT((Pfn1->u3.e1.PageLocation == ModifiedPageList) || (Pfn1->u3.e1.PageLocation == StandbyPageList)); - /* Unlink it and put it back in free list */ + /* Unlink it and temporarily mark it as active */ MiUnlinkPageFromList(Pfn1); + Pfn1->u3.e2.ReferenceCount++; Pfn1->u3.e1.PageLocation = ActiveAndValid; - /* Bring it back into the free list */ - MiInsertPageInFreeList(PageFrameIndex); + /* This will put it back in free list and clean properly up */ + MI_SET_PFN_DELETED(Pfn1); + MiDecrementReferenceCount(Pfn1, PageFrameIndex); } return; } @@ -470,6 +474,11 @@ MiDeletePte(IN PMMPTE PointerPte, #if (_MI_PAGING_LEVELS == 2) } #endif + /* Drop the share count on the page table */ + PointerPde = MiPteToPde(PointerPte); + MiDecrementShareCount(MiGetPfnEntry(PointerPde->u.Hard.PageFrameNumber), + PointerPde->u.Hard.PageFrameNumber); + /* Drop the share count */ MiDecrementShareCount(Pfn1, PageFrameIndex);