Author: arty
Date: Fri Jan  8 11:26:30 2010
New Revision: 44995

URL: http://svn.reactos.org/svn/reactos?rev=44995&view=rev
Log:
Keep pages referenced while paging out so we can follow the LRU chain in all 
cases.
Explicitly handle STATUS_MM_RESTART_OPERATION like we used to.
My previous code for pulling in a page, then faulting it into the address space
wasn't correct; we take the easier route of pretending we're starting fresh once
we've pulled the page into the section.
MmDeleteSectionAssociation is now necessary since we may not hold the (quite) 
last
reference.

Modified:
    branches/arty-newcc/ntoskrnl/include/internal/mm.h
    branches/arty-newcc/ntoskrnl/mm/balance.c
    branches/arty-newcc/ntoskrnl/mm/freelist.c
    branches/arty-newcc/ntoskrnl/mm/mmfault.c
    branches/arty-newcc/ntoskrnl/mm/rmap.c
    branches/arty-newcc/ntoskrnl/mm/section/data.c
    branches/arty-newcc/ntoskrnl/mm/section/fault.c
    branches/arty-newcc/ntoskrnl/mm/section/pagefile.c

Modified: branches/arty-newcc/ntoskrnl/include/internal/mm.h
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/internal/mm.h?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/mm.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/mm.h [iso-8859-1] Fri Jan  8 
11:26:30 2010
@@ -2207,7 +2207,7 @@
 _MmTryToLockAddressSpace(IN PMMSUPPORT AddressSpace, const char *file, int 
line)
 {
        BOOLEAN Result = 
KeTryToAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, 
Vm)->AddressCreationLock);
-       DbgPrint("(%s:%d) Try Lock Address Space %x -> %s\n", file, line, 
AddressSpace, Result ? "true" : "false");
+       //DbgPrint("(%s:%d) Try Lock Address Space %x -> %s\n", file, line, 
AddressSpace, Result ? "true" : "false");
        return Result;
 }
 

Modified: branches/arty-newcc/ntoskrnl/mm/balance.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/balance.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] Fri Jan  8 11:26:30 
2010
@@ -33,7 +33,7 @@
 
 BOOLEAN MiBalancerInitialized = FALSE;
 MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
-/*static*/ ULONG MiMinimumAvailablePages = 0x3000;
+/*static*/ ULONG MiMinimumAvailablePages = 128; 
 static ULONG MiNrTotalPages;
 static LIST_ENTRY AllocationListHead;
 static KSPIN_LOCK AllocationListLock;
@@ -137,21 +137,19 @@
 MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
 {
     PFN_TYPE CurrentPage;
-    PFN_TYPE NextPage;
     NTSTATUS Status;
     
     (*NrFreedPages) = 0;
        DPRINT("Trimming user memory (want %d)\n", Target);
-    
+
+       // Current page is referenced
     CurrentPage = MmGetLRUFirstUserPage();
     while (CurrentPage != 0 && Target > 0)
     {
-               //DPRINT("Trying page %x\n", CurrentPage);
-        NextPage = MmGetLRUNextUserPage(CurrentPage);
         Status = MmPageOutPhysicalAddress(CurrentPage);
-               //DPRINT("Status: %x\n", Status);
         if (NT_SUCCESS(Status))
         {
+                       MmRemoveLRUUserPage(CurrentPage);
             Target--;
             (*NrFreedPages)++;
         }
@@ -160,9 +158,12 @@
                        MmRemoveLRUUserPage(CurrentPage);
                        MmInsertLRULastUserPage(CurrentPage);
                }
-        
-        CurrentPage = NextPage;
+
+               // Reference is updated
+               CurrentPage = MmGetLRUNextUserPage(CurrentPage);
     }
+       if (CurrentPage)
+               MmDereferencePage(CurrentPage); // Dereference matches 
MmGetLRUFirst/Next
        DPRINT("Done\n");
     return(STATUS_SUCCESS);
 }

Modified: branches/arty-newcc/ntoskrnl/mm/freelist.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/freelist.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/freelist.c [iso-8859-1] Fri Jan  8 11:26:30 
2010
@@ -107,6 +107,7 @@
    }
    PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
    ASSERT_PFN(PageDescriptor);
+   MmReferencePage(PageDescriptor - MmPfnDatabase);
    KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
    return PageDescriptor - MmPfnDatabase;
 }
@@ -148,7 +149,9 @@
       return 0;
    }
    PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
+   MmReferencePage(PageDescriptor - MmPfnDatabase);
    KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
+   MmDereferencePage(PreviousPfn);
    return PageDescriptor - MmPfnDatabase;
 }
 
@@ -156,7 +159,10 @@
 NTAPI
 MmRemoveLRUUserPage(PFN_TYPE Page)
 {
+   KIRQL oldIrql;
+   oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
    RemoveEntryList(&MiGetPfnEntry(Page)->ListEntry);
+   KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
 }
 
 PFN_NUMBER

Modified: branches/arty-newcc/ntoskrnl/mm/mmfault.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mmfault.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mmfault.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mmfault.c [iso-8859-1] Fri Jan  8 11:26:30 
2010
@@ -172,6 +172,11 @@
                          ASSERT(FALSE);
                  DPRINT("Restarting fault %x\n", Address);
                  Status = STATUS_MM_RESTART_OPERATION;
+         }
+         else if (Status == STATUS_MM_RESTART_OPERATION)
+         {
+                 // Clean slate
+                 RtlZeroMemory(&Resources, sizeof(Resources));
          }
          else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
          {
@@ -355,6 +360,11 @@
                        DPRINT("Done waiting for %x\n", Address);
                        Status = STATUS_MM_RESTART_OPERATION;
                }
+               else if (Status == STATUS_MM_RESTART_OPERATION)
+               {
+                       // Clean slate
+                       RtlZeroMemory(&Resources, sizeof(Resources));
+               }
                else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
                {
                        if (Thread->ActiveFaultCount > 1)
@@ -413,7 +423,8 @@
        PETHREAD Thread;
        PMMSUPPORT AddressSpace;
        NTSTATUS Status;
-       
+
+       Address &= ~(PAGE_SIZE - 1);
        DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
        
        Thread = PsGetCurrentThread();
@@ -461,6 +472,8 @@
               IN PVOID TrapInformation)
 {
     PMEMORY_AREA MemoryArea;
+
+       Address = (PVOID)(((ULONG_PTR)Address) & ~(PAGE_SIZE - 1));
 
     /* Cute little hack for ROS */
     if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)

Modified: branches/arty-newcc/ntoskrnl/mm/rmap.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/rmap.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] Fri Jan  8 11:26:30 2010
@@ -349,7 +349,7 @@
 
           if (MmGetRmapListHeadPage(Page))
           {
-                  DPRINT1("Page %x was re-acquired while we were evicting 
it\n", Page);
+                  DPRINT("Page %x was re-acquired while we were evicting 
it\n", Page);
                   MmLockSectionSegment(Segment);
                   MiSetPageEntrySectionSegment(Segment, &FileOffset, Dirty ? 
DIRTY_SSE(MAKE_PFN_SSE(SectionPage)) : MAKE_PFN_SSE(SectionPage));
                   MmUnlockSectionSegment(Segment);
@@ -366,7 +366,7 @@
 
                   if (!Evicted && SectionPage)
                   {
-                          DPRINT1
+                          DPRINT
                                   ("Failed to page out, replacing %x at %x in 
segment %x\n",
                                        SectionPage, FileOffset.LowPart, 
Segment);
                           MmLockSectionSegment(Segment);

Modified: branches/arty-newcc/ntoskrnl/mm/section/data.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/data.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/data.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/data.c [iso-8859-1] Fri Jan  8 
11:26:30 2010
@@ -1174,7 +1174,7 @@
                        MiWriteBackPage(FileObject, FileOffset, PAGE_SIZE, 
OldPage);
                        DPRINT("Dereference page %x\n", OldPage);
                }
-               ASSERT(MmGetReferenceCountPage(OldPage) == 1);
+               MmDeleteSectionAssociation(OldPage);
                MmDereferencePage(OldPage);
                DPRINT("Done\n");
        }

Modified: branches/arty-newcc/ntoskrnl/mm/section/fault.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/fault.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/fault.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/fault.c [iso-8859-1] Fri Jan  8 
11:26:30 2010
@@ -97,6 +97,8 @@
                                                  
&MemoryArea->Data.SectionData.RegionListHead,
                                                  Address, NULL);
 
+       ASSERT(Region);
+
        TotalOffset.QuadPart += 
MemoryArea->Data.SectionData.ViewOffset.QuadPart;
        FileOffset = TotalOffset;
 
@@ -145,27 +147,41 @@
 
        if (Required->State && Required->Page[0])
        {
-               DPRINT("Have file and page, set page in section @ %x\n", 
TotalOffset.LowPart);
-               Status = MiSetPageEntrySectionSegment
-                       (Segment, &TotalOffset, Entry = 
MAKE_PFN_SSE(Required->Page[0]));
-               if (NT_SUCCESS(Status))
-               {
-                       MmReferencePage(Required->Page[0]);
+               DPRINT("Have file and page, set page %x in section @ %x\n", 
Required->Page[0], TotalOffset.LowPart);
+               if (Required->State & 2)
+               {
+                       Status = MiSetPageEntrySectionSegment
+                               (Segment, &TotalOffset, Entry = 
MAKE_PFN_SSE(Required->Page[0]));
+                       if (!NT_SUCCESS(Status))
+                       {
+                               MmDereferencePage(Required->Page[0]);
+                       }
+                       MmUnlockSectionSegment(Segment);
+                       DPRINT("XXX Set Event %x\n", Status);
+                       KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+                       DPRINT("Status %x\n", Status);
+                       return STATUS_MM_RESTART_OPERATION;
+               }
+               else
+               {
+                       DPRINT("Set %x in address space @ %x\n", 
Required->Page[0], Address);
                        Status = MmCreateVirtualMapping(Process, Address, 
Attributes, Required->Page, 1);
                        if (NT_SUCCESS(Status))
                        {
                                MmInsertRmap(Required->Page[0], Process, 
Address);
+                               if (Locked) MmLockPage(Required->Page[0]);
                        }
                        else
                        {
+                               // Drop the reference for our address space ...
                                MmDereferencePage(Required->Page[0]);
                        }
-               }
-               MmUnlockSectionSegment(Segment);
-               DPRINT("XXX Set Event %x\n", Status);
-               KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
-               DPRINT("Status %x\n", Status);
-               return Status;
+                       MmUnlockSectionSegment(Segment);
+                       DPRINT("XXX Set Event %x\n", Status);
+                       KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+                       DPRINT("Status %x\n", Status);
+                       return Status;
+               }
        }
        else if (MmIsPageSwapEntry(Process, Address))
        {
@@ -180,8 +196,7 @@
                else
                {
                        DPRINT("Swap in\n");
-                       MmCreatePageFileMapping(Process, Address, 
MM_WAIT_ENTRY);
-                       Required->State = 7;
+                       Required->State = 1;
                        Required->Consumer = Consumer;
                        Required->SwapEntry = SwapEntry;
                        Required->DoAcquisition = MiSwapInPage;
@@ -201,9 +216,7 @@
                else
                {
                        DPRINT("Swap in\n");
-                       MmCreatePageFileMapping(Process, Address, 
MM_WAIT_ENTRY);
-                       MiSetPageEntrySectionSegment(Segment, &TotalOffset, 
MAKE_SWAP_SSE(MM_WAIT_ENTRY));
-                       Required->State = 7;
+                       Required->State = 3;
                        Required->Consumer = Consumer;
                        Required->SwapEntry = SwapEntry;
                        Required->DoAcquisition = MiSwapInPage;
@@ -220,6 +233,7 @@
                if (NT_SUCCESS(Status))
                {
                        MmInsertRmap(Page, Process, Address);
+                       if (Locked) MmLockPage(Required->Page[0]);
                        Required->Page[0] = 0;
                }
                DPRINT("XXX Set Event %x\n", Status);
@@ -241,7 +255,7 @@
                          (IMAGE_SCN_CNT_CODE | 
IMAGE_SCN_CNT_INITIALIZED_DATA))))
                {
                        DPRINT("Read from file %08x\n", FileOffset.LowPart);
-                       Required->State = 1;
+                       Required->State = 3;
                        Required->Context = Section->FileObject;
                        Required->Consumer = Consumer;
                        Required->FileOffset = FileOffset;
@@ -252,7 +266,7 @@
                else
                {
                        DPRINT("Get Page\n");
-                       Required->State = 1;
+                       Required->State = 3;
                        Required->Amount = 1;
                        Required->Consumer = Consumer;
                        Required->DoAcquisition = MiGetOnePage;
@@ -338,45 +352,47 @@
 
        if (Required->Page[0] && Required->State)
        {
-               Page = Required->Page[0];
-
                DPRINT("Have Page: %x %d\n", Page, Required->State);
-           if (Required->State & 1)
+               if (Required->State & 2)
                {
                        DPRINT("Set in section @ %x\n", Offset.LowPart);
                        Status = MiSetPageEntrySectionSegment
-                               (Segment, &Offset, MAKE_PFN_SSE(Page));
-               }
-
-               if (Required->State & 2)
-               {
-                       DPRINT("Set in address space @ %x\n", Address);
-                       Status = MmCreateVirtualMapping
-                               (Process, Address, Attributes, &Page, 1);
+                               (Segment, &Offset, Entry = 
MAKE_PFN_SSE(Required->Page[0]));
+                       if (!NT_SUCCESS(Status))
+                       {
+                               MmDereferencePage(Required->Page[0]);
+                       }
+                       MmUnlockSectionSegment(Segment);
+                       DPRINT("XXX Set Event %x\n", Status);
+                       KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+                       DPRINT("Status %x\n", Status);
+                       return STATUS_MM_RESTART_OPERATION;
+               }
+               else
+               {
+                       DPRINT("Set %x in address space @ %x\n", 
Required->Page[0], Address);
+                       Status = MmCreateVirtualMapping(Process, Address, 
Attributes, Required->Page, 1);
                        if (NT_SUCCESS(Status))
                        {
-                               MmInsertRmap(Page, Process, Address);
-                               if (Locked) MmLockPage(Page);
+                               MmInsertRmap(Required->Page[0], Process, 
Address);
+                               if (Locked) MmLockPage(Required->Page[0]);
                        }
-               }
-
-               if (Required->State & 4)
-               {
-                       DPRINT("Take a reference\n");
-                       Status = STATUS_SUCCESS;
-                       MmReferencePage(Page);
-               }
-
-               MmUnlockSectionSegment(Segment);
-               DPRINT("XXX Set Event %x\n", Status);
-               KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
-               DPRINT("Done: %x\n", Status);
-               return Status;
+                       else
+                       {
+                               // Drop the reference for our address space
+                               MmDereferencePage(Required->Page[0]);
+                       }
+                       MmUnlockSectionSegment(Segment);
+                       DPRINT("XXX Set Event %x\n", Status);
+                       KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+                       DPRINT("Done: %x\n", Status);
+                       return Status;
+               }
        }
 
        if (Entry == 0 && !HasSwapEntry && Offset.QuadPart < 
PAGE_ROUND_UP(Segment->RawLength.QuadPart))
        {
-               Required->State = 7;
+               Required->State = 3;
                Required->Context = Section->FileObject;
                Required->Consumer = MC_USER;
                Required->FileOffset.QuadPart = Offset.QuadPart + 
Segment->Image.FileOffset;
@@ -398,8 +414,7 @@
                 * Must be private page we have swapped out.
                 */
                DPRINT("Private swapped out page\n");
-               MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
-               Required->State = 2;
+               Required->State = 1;
                Required->Consumer = MC_USER;
                Required->DoAcquisition = MiSwapInPage;
                MmUnlockSectionSegment(Segment);
@@ -414,10 +429,9 @@
        else if (IS_SWAP_FROM_SSE(Entry))
        {
                DPRINT("Swap in section page\n");
-               Required->State = 7;
+               Required->State = 3;
                Required->Consumer = MC_USER;
                MmGetPageFileMapping(Process, (PVOID)PAddress, 
&Required->SwapEntry);
-               MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
                Required->DoAcquisition = MiSwapInPage;
                MmUnlockSectionSegment(Segment);
                return STATUS_MORE_PROCESSING_REQUIRED;
@@ -430,7 +444,7 @@
                          Offset.QuadPart >= 
PAGE_ROUND_UP(Segment->RawLength.QuadPart))) 
        {
                DPRINT("BSS Page\n");
-               Required->State = 2;
+               Required->State = 1;
                Required->Amount = 1;
                Required->Consumer = MC_USER;
                Required->DoAcquisition = MiGetOnePage;
@@ -835,7 +849,6 @@
                        }
                        DPRINT("MiWriteSwapPage (%x -> %x)\n", OurPage, 
Required->SwapEntry);
                        Required->DoAcquisition = MiWriteSwapPage;
-                       MmCreatePageFileMapping(Process, Address, 
MM_WAIT_ENTRY);
                        MmUnlockSectionSegment(Segment);
                        return STATUS_MORE_PROCESSING_REQUIRED;
                }

Modified: branches/arty-newcc/ntoskrnl/mm/section/pagefile.c
URL: 
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/pagefile.c?rev=44995&r1=44994&r2=44995&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/pagefile.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/pagefile.c [iso-8859-1] Fri Jan  8 
11:26:30 2010
@@ -176,7 +176,7 @@
                                Status = STATUS_PAGEFILE_QUOTA;
                        else
                        {
-                               DPRINT("Writing to swap page\n");
+                               DPRINT1("Writing to swap %x page %x\n", Swap, 
Page);
                                Status = MmWriteToSwapPage(Swap, Page);
                        }
 
@@ -207,7 +207,7 @@
 
        if (WritePage)
        {
-               DPRINT("Segment %x FileObject %x Offset %x\n", Segment, 
Segment->FileObject, FileOffset->LowPart);
+               DPRINT1("MiWriteBackPage(Segment %x FileObject %x Offset 
%x)\n", Segment, Segment->FileObject, FileOffset->LowPart);
                Status = MiWriteBackPage(Segment->FileObject, FileOffset, 
PAGE_SIZE, Page);
        }
 
@@ -215,6 +215,7 @@
        {
                DPRINT("Removing page %x for real\n", Page);
                MmSetSavedSwapEntryPage(Page, 0);
+               MmDeleteSectionAssociation(Page);
                MmDereferencePage(Page);
        }
 


Reply via email to