[NTOS/MM]
authorJérôme Gardou <jerome.gardou@reactos.org>
Mon, 25 Aug 2014 12:33:49 +0000 (12:33 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Mon, 25 Aug 2014 12:33:49 +0000 (12:33 +0000)
 - 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

reactos/ntoskrnl/mm/ARM3/pagfault.c
reactos/ntoskrnl/mm/ARM3/virtual.c

index df4dbeb..f78a445 100644 (file)
@@ -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)
index 932e1d0..ce61601 100644 (file)
@@ -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);