Author: arty
Date: Tue Jan 5 16:15:30 2010
New Revision: 44944
URL:
http://svn.reactos.org/svn/reactos?rev=44944&view=rev
Log:
Fix failure case for pageout (including pulling a page that's being swapped out),
Reorder operations on not present to handle wait entries properly.
Fix some balancer issues and initialize rmap earlier, as there's no reason to wait.
Removed:
branches/arty-newcc/ntoskrnl/mm/pageop.c
Modified:
branches/arty-newcc/ntoskrnl/mm/anonmem.c
branches/arty-newcc/ntoskrnl/mm/balance.c
branches/arty-newcc/ntoskrnl/mm/elf.inc.h
branches/arty-newcc/ntoskrnl/mm/elf32.c
branches/arty-newcc/ntoskrnl/mm/mmfault.c
branches/arty-newcc/ntoskrnl/mm/mminit.c
branches/arty-newcc/ntoskrnl/mm/rmap.c
branches/arty-newcc/ntoskrnl/mm/section/fault.c
branches/arty-newcc/ntoskrnl/mm/section/pagefile.c
Modified: branches/arty-newcc/ntoskrnl/mm/anonmem.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/anonmem.…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/anonmem.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -790,49 +790,12 @@
{
PLIST_ENTRY current_entry;
PMM_REGION current;
- ULONG i;
DPRINT("MmFreeVirtualMemory(Process %p MemoryArea %p)\n", Process,
MemoryArea);
/* Mark this memory area as about to be deleted. */
MemoryArea->DeleteInProgress = TRUE;
-
- /*
- * Wait for any ongoing paging operations. Notice that since we have
- * flagged this memory area as deleted no more page ops will be added.
- */
- if (MemoryArea->PageOpCount > 0)
- {
- ULONG_PTR MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
- (ULONG_PTR)MemoryArea->StartingAddress;
- const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
-
- for (i = 0; i < nPages && MemoryArea->PageOpCount != 0; ++i)
- {
- PMM_PAGEOP PageOp;
- PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId,
- (PVOID)((ULONG_PTR)MemoryArea->StartingAddress + (i
* PAGE_SIZE)),
- NULL, 0);
- if (PageOp != NULL)
- {
- NTSTATUS Status;
- MmUnlockAddressSpace(&Process->Vm);
- Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
- 0,
- KernelMode,
- FALSE,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- DPRINT1("Failed to wait for page op\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- MmLockAddressSpace(&Process->Vm);
- MmReleasePageOp(PageOp);
- }
- }
- }
/* Free all the individual segments. */
current_entry = MemoryArea->Data.VirtualMemoryData.RegionListHead.Flink;
Modified: branches/arty-newcc/ntoskrnl/mm/balance.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/balance.…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/balance.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -31,6 +31,7 @@
/* GLOBALS ******************************************************************/
+BOOLEAN MiBalancerInitialized = FALSE;
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
/*static*/ ULONG MiMinimumAvailablePages = 128;
static ULONG MiNrTotalPages;
@@ -170,8 +171,9 @@
MiIsBalancerThread(VOID)
{
return
- PsGetCurrentThread()->Cid.UniqueThread ==
- MiBalancerThreadId.UniqueThread;
+ !MiBalancerInitialized ||
+ (PsGetCurrentThread()->Cid.UniqueThread ==
+ MiBalancerThreadId.UniqueThread);
}
/*
@@ -284,6 +286,8 @@
WaitObjects[0] = &MiBalancerEvent;
WaitObjects[1] = &MiBalancerTimer;
+
+ MiBalancerInitialized = TRUE;
while (1)
{
@@ -335,23 +339,14 @@
{
KPRIORITY Priority;
NTSTATUS Status;
-#if !defined(__GNUC__)
-
- LARGE_INTEGER dummyJunkNeeded;
- dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */
- ;
-#endif
-
+ LARGE_INTEGER BalancerInterval;
+ BalancerInterval.QuadPart = -20000000; /* 2 sec */
KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&MiBalancerContinue, SynchronizationEvent, FALSE);
KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer);
KeSetTimerEx(&MiBalancerTimer,
-#if defined(__GNUC__)
- (LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */
-#else
- dummyJunkNeeded,
-#endif
+ BalancerInterval,
2000, /* 2 sec */
NULL);
Modified: branches/arty-newcc/ntoskrnl/mm/elf.inc.h
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/elf.inc.…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/elf.inc.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/elf.inc.h [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -8,8 +8,6 @@
#endif
#include <elf/elf.h>
-
-#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
/* TODO: Intsafe should be made into a library, as it's generally useful */
static __inline BOOLEAN Intsafe_CanAddULongPtr
Modified: branches/arty-newcc/ntoskrnl/mm/elf32.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/elf32.c?…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/elf32.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/elf32.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -9,8 +9,6 @@
#include <ntoskrnl.h>
#define __ELF_WORD_SIZE 32
#include "elf.inc.h"
-
-#define IMAGE_FILE_MACHINE_UNKNOWN 0
extern NTSTATUS NTAPI Elf64FmtCreateSection
(
Modified: branches/arty-newcc/ntoskrnl/mm/mmfault.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mmfault.…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mmfault.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mmfault.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -161,6 +161,7 @@
if (Status == STATUS_SUCCESS + 1)
{
// Wait page ...
+ DPRINT1("Waiting for %x\n", Address);
if (!NT_SUCCESS
(KeWaitForSingleObject
(&MmWaitPageEvent,
@@ -169,6 +170,7 @@
FALSE,
NULL)))
ASSERT(FALSE);
+ DPRINT1("Restarting fault %x\n", Address);
Status = STATUS_MM_RESTART_OPERATION;
}
else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
@@ -341,6 +343,7 @@
if (Status == STATUS_SUCCESS + 1)
{
// Wait page ...
+ DPRINT1("Waiting for %x\n", Address);
if (!NT_SUCCESS
(KeWaitForSingleObject
(&MmWaitPageEvent,
@@ -349,6 +352,7 @@
FALSE,
NULL)))
ASSERT(FALSE);
+ DPRINT1("Done waiting for %x\n", Address);
Status = STATUS_MM_RESTART_OPERATION;
}
else if (Status == STATUS_MORE_PROCESSING_REQUIRED)
Modified: branches/arty-newcc/ntoskrnl/mm/mminit.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/mminit.c…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/mminit.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -467,7 +467,10 @@
/* Dump the address space */
MiDbgDumpAddressSpace();
-
+
+ /* Initialize rmap implementation */
+ MmInitializeRmapList();
+
/* Initialize paged pool */
MmInitializePagedPool();
@@ -496,8 +499,6 @@
}
else if (Phase == 1)
{
- MmInitializeRmapList();
- MmInitializePageOp();
MmInitSectionImplementation();
MmInitPagingFile();
Removed: branches/arty-newcc/ntoskrnl/mm/pageop.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/pageop.c…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/pageop.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/pageop.c (removed)
@@ -1,268 +1,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/pageop.c
- * PURPOSE: No purpose listed.
- *
- * PROGRAMMERS: David Welch (welch(a)cwcom.net)
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, MmInitializePageOp)
-#endif
-
-
-/* GLOBALS *******************************************************************/
-
-#define PAGEOP_HASH_TABLE_SIZE (32)
-
-static KSPIN_LOCK MmPageOpHashTableLock;
-static PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE];
-static NPAGED_LOOKASIDE_LIST MmPageOpLookasideList;
-
-/* FUNCTIONS *****************************************************************/
-
-VOID
-NTAPI
-MmReleasePageOp(PMM_PAGEOP PageOp)
-/*
- * FUNCTION: Release a reference to a page operation descriptor
- */
-{
- KIRQL oldIrql;
- PMM_PAGEOP PrevPageOp;
-
- KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
- PageOp->ReferenceCount--;
- if (PageOp->ReferenceCount > 0)
- {
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- return;
- }
- (void)InterlockedDecrementUL(&PageOp->MArea->PageOpCount);
- PrevPageOp = MmPageOpHashTable[PageOp->Hash];
- if (PrevPageOp == PageOp)
- {
- MmPageOpHashTable[PageOp->Hash] = PageOp->Next;
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp);
- return;
- }
- while (PrevPageOp->Next != NULL)
- {
- if (PrevPageOp->Next == PageOp)
- {
- PrevPageOp->Next = PageOp->Next;
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp);
- return;
- }
- PrevPageOp = PrevPageOp->Next;
- }
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- KeBugCheck(MEMORY_MANAGEMENT);
-}
-
-PMM_PAGEOP
-NTAPI
-MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
- PMM_SECTION_SEGMENT Segment, ULONG Offset)
-{
- ULONG_PTR Hash;
- KIRQL oldIrql;
- PMM_PAGEOP PageOp;
-
- /*
- * Calcuate the hash value for pageop structure
- */
- if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
- {
- Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
- }
- else
- {
- Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
- }
- Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
-
- KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
-
- /*
- * Check for an existing pageop structure
- */
- PageOp = MmPageOpHashTable[Hash];
- while (PageOp != NULL)
- {
- if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
- {
- if (PageOp->Segment == Segment &&
- PageOp->Offset == Offset)
- {
- break;
- }
- }
- else
- {
- if (PageOp->Pid == Pid &&
- PageOp->Address == Address)
- {
- break;
- }
- }
- PageOp = PageOp->Next;
- }
-
- /*
- * If we found an existing pageop then increment the reference count
- * and return it.
- */
- if (PageOp != NULL)
- {
- PageOp->ReferenceCount++;
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- return(PageOp);
- }
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- return(NULL);
-}
-
-PMM_PAGEOP
-NTAPI
-MmGetPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
- PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOLEAN First)
-/*
- * FUNCTION: Get a page operation descriptor corresponding to
- * the memory area and either the segment, offset pair or the
- * pid, address pair.
- */
-{
- ULONG_PTR Hash;
- KIRQL oldIrql;
- PMM_PAGEOP PageOp;
-
- /*
- * Calcuate the hash value for pageop structure
- */
- if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
- {
- Hash = (((ULONG_PTR)Segment) | (((ULONG_PTR)Offset) / PAGE_SIZE));
- }
- else
- {
- Hash = (((ULONG_PTR)Pid) | (((ULONG_PTR)Address) / PAGE_SIZE));
- }
- Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
-
- KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
-
- /*
- * Check for an existing pageop structure
- */
- PageOp = MmPageOpHashTable[Hash];
- while (PageOp != NULL)
- {
- if (MArea->Type == MEMORY_AREA_SECTION_VIEW)
- {
- if (PageOp->Segment == Segment &&
- PageOp->Offset == Offset)
- {
- break;
- }
- }
- else
- {
- if (PageOp->Pid == Pid &&
- PageOp->Address == Address)
- {
- break;
- }
- }
- PageOp = PageOp->Next;
- }
-
- /*
- * If we found an existing pageop then increment the reference count
- * and return it.
- */
- if (PageOp != NULL)
- {
- if (First)
- {
- PageOp = NULL;
- }
- else
- {
- PageOp->ReferenceCount++;
- }
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- return(PageOp);
- }
-
- /*
- * Otherwise add a new pageop.
- */
- PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList);
- if (PageOp == NULL)
- {
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- KeBugCheck(MEMORY_MANAGEMENT);
- return(NULL);
- }
-
- if (MArea->Type != MEMORY_AREA_SECTION_VIEW)
- {
- PageOp->Pid = Pid;
- PageOp->Address = Address;
- }
- else
- {
- PageOp->Segment = Segment;
- PageOp->Offset = Offset;
- }
- PageOp->ReferenceCount = 1;
- PageOp->Next = MmPageOpHashTable[Hash];
- PageOp->Hash = Hash;
- PageOp->Thread = PsGetCurrentThread();
- PageOp->Abandoned = FALSE;
- PageOp->Status = STATUS_PENDING;
- PageOp->OpType = OpType;
- PageOp->MArea = MArea;
- KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
- MmPageOpHashTable[Hash] = PageOp;
- (void)InterlockedIncrementUL(&MArea->PageOpCount);
-
- KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
- return(PageOp);
-}
-
-VOID
-INIT_FUNCTION
-NTAPI
-MmInitializePageOp(VOID)
-{
- memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable));
- KeInitializeSpinLock(&MmPageOpHashTableLock);
-
- ExInitializeNPagedLookasideList (&MmPageOpLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(MM_PAGEOP),
- TAG_MM_PAGEOP,
- 50);
-}
-
-
-
-
-
-
-
-
-
Modified: branches/arty-newcc/ntoskrnl/mm/rmap.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/rmap.c?r…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/rmap.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -342,19 +342,30 @@
{
DPRINT("About to finalize section page %x %s\n", Page, Dirty ?
"dirty" : "clean");
- Evicted =
- NT_SUCCESS(Status) &&
- NT_SUCCESS(MmFinalizeSectionPageOut(Segment, &FileOffset, Page, Dirty));
-
- if (!Evicted && SectionPage)
- {
- DPRINT
- ("Failed to page out, replacing %x at %x in segment %x\n",
- SectionPage, FileOffset.LowPart, Segment);
+ if (MmGetRmapListHeadPage(Page))
+ {
+ DPRINT1("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);
KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+ }
+ else
+ {
+ Evicted =
+ NT_SUCCESS(Status) &&
+ NT_SUCCESS(MmFinalizeSectionPageOut(Segment, &FileOffset, Page, Dirty));
+
+ if (!Evicted && SectionPage)
+ {
+ DPRINT1
+ ("Failed to page out, replacing %x at %x in segment %x\n",
+ SectionPage, FileOffset.LowPart, Segment);
+ MmLockSectionSegment(Segment);
+ MiSetPageEntrySectionSegment(Segment, &FileOffset, Dirty ?
DIRTY_SSE(MAKE_PFN_SSE(SectionPage)) : MAKE_PFN_SSE(SectionPage));
+ MmUnlockSectionSegment(Segment);
+ KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+ }
}
}
Modified: branches/arty-newcc/ntoskrnl/mm/section/fault.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/fault.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/fault.c [iso-8859-1] Tue Jan 5 16:15:30 2010
@@ -71,7 +71,7 @@
PMM_REGION Region;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
- DPRINT1("Not Present: %p %p (%p-%p)\n", AddressSpace, Address,
MemoryArea->StartingAddress, MemoryArea->EndingAddress);
+ DPRINT("Not Present: %p %p (%p-%p)\n", AddressSpace, Address,
MemoryArea->StartingAddress, MemoryArea->EndingAddress);
/*
* There is a window between taking the page fault and locking the
@@ -115,6 +115,7 @@
{
DPRINT("FileName %wZ\n", &Segment->FileObject->FileName);
}
+
DPRINT("Total Offset %08x%08x\n", TotalOffset.HighPart, TotalOffset.LowPart);
/*
@@ -151,8 +152,73 @@
DPRINT("Normal %x\n", Attributes);
}
-grab_page:
- if (Entry && !IS_SWAP_FROM_SSE(Entry))
+ 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]);
+ Status = MmCreateVirtualMapping(Process, Address, Attributes, Required->Page, 1);
+ if (NT_SUCCESS(Status))
+ {
+ MmInsertRmap(Required->Page[0], Process, Address);
+ }
+ else
+ {
+ MmDereferencePage(Required->Page[0]);
+ }
+ }
+ MmUnlockSectionSegment(Segment);
+ DPRINT("XXX Set Event %x\n", Status);
+ KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
+ DPRINT1("Status %x\n", Status);
+ return Status;
+ }
+ else if (MmIsPageSwapEntry(Process, Address))
+ {
+ SWAPENTRY SwapEntry;
+ MmGetPageFileMapping(Process, Address, &SwapEntry);
+ if (SwapEntry == MM_WAIT_ENTRY)
+ {
+ DPRINT1("Wait for page entry in section\n");
+ return STATUS_SUCCESS + 1;
+ }
+ else
+ {
+ DPRINT("Swap in\n");
+ MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
+ Required->State = 7;
+ Required->Consumer = Consumer;
+ Required->SwapEntry = SwapEntry;
+ Required->DoAcquisition = MiSwapInPage;
+ MmUnlockSectionSegment(Segment);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ }
+ else if (IS_SWAP_FROM_SSE(Entry))
+ {
+ SWAPENTRY SwapEntry = SWAPENTRY_FROM_SSE(Entry);
+ if (SwapEntry == MM_WAIT_ENTRY)
+ {
+ DPRINT1("Wait for page entry in section\n");
+ return STATUS_SUCCESS + 1;
+ }
+ else
+ {
+ DPRINT("Swap in\n");
+ MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
+ MiSetPageEntrySectionSegment(Segment, &TotalOffset,
MAKE_SWAP_SSE(MM_WAIT_ENTRY));
+ Required->State = 7;
+ Required->Consumer = Consumer;
+ Required->SwapEntry = SwapEntry;
+ Required->DoAcquisition = MiSwapInPage;
+ MmUnlockSectionSegment(Segment);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ }
+ else if (Entry && !IS_SWAP_FROM_SSE(Entry))
{
PFN_TYPE Page = PFN_FROM_SSE(Entry);
DPRINT("Page %x\n", Page);
@@ -166,23 +232,10 @@
DPRINT("XXX Set Event %x\n", Status);
KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
MmUnlockSectionSegment(Segment);
+ DPRINT1("Status %x\n", Status);
return Status;
}
-
- 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))
- {
- goto grab_page;
- }
- MmUnlockSectionSegment(Segment);
- return Status;
- }
-
- if (Entry == 0)
+ else
{
DPRINT("Get page into section\n");
/*
@@ -213,17 +266,6 @@
MmUnlockSectionSegment(Segment);
return STATUS_MORE_PROCESSING_REQUIRED;
}
- }
- else
- {
- DPRINT("Swap in\n");
- Required->State = 7;
- Required->Consumer = Consumer;
- Required->SwapEntry = SWAPENTRY_FROM_SSE(Entry);
- MiSetPageEntrySectionSegment(Segment, &TotalOffset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
- Required->DoAcquisition = MiSwapInPage;
- MmUnlockSectionSegment(Segment);
- return STATUS_MORE_PROCESSING_REQUIRED;
}
}
@@ -311,6 +353,7 @@
DPRINT("Set in section @ %x\n", Offset.LowPart);
Status = MiSetPageEntrySectionSegment
(Segment, &Offset, MAKE_PFN_SSE(Page));
+ KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
}
if (Required->State & 2)
@@ -330,6 +373,7 @@
if (Required->State & 4)
{
DPRINT("Take a reference\n");
+ Status = STATUS_SUCCESS;
MmReferencePage(Page);
}
@@ -349,8 +393,7 @@
MmUnlockSectionSegment(Segment);
return STATUS_MORE_PROCESSING_REQUIRED;
}
-
- if (HasSwapEntry)
+ else if (HasSwapEntry)
{
MmGetPageFileMapping(Process, (PVOID)PAddress, &Required->SwapEntry);
if (Required->SwapEntry == MM_WAIT_ENTRY)
@@ -363,28 +406,18 @@
* Must be private page we have swapped out.
*/
DPRINT("Private swapped out page\n");
+ MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
Required->State = 2;
Required->Consumer = MC_USER;
- MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
Required->DoAcquisition = MiSwapInPage;
MmUnlockSectionSegment(Segment);
return STATUS_MORE_PROCESSING_REQUIRED;
}
-
- /*
- * Map anonymous memory for BSS sections
- */
- if (Entry == 0 ||
- (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) ||
- Offset.QuadPart >= PAGE_ROUND_UP(Segment->RawLength.QuadPart))
- {
- DPRINT("BSS Page\n");
- Required->State = 2;
- Required->Amount = 1;
- Required->Consumer = MC_USER;
- Required->DoAcquisition = MiGetOnePage;
- MmUnlockSectionSegment(Segment);
- return STATUS_MORE_PROCESSING_REQUIRED;
+ else if (IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
+ {
+ DPRINT("Waiting\n");
+ MmUnlockSectionSegment(Segment);
+ return STATUS_SUCCESS + 1;
}
else if (IS_SWAP_FROM_SSE(Entry))
{
@@ -394,6 +427,21 @@
MmGetPageFileMapping(Process, (PVOID)PAddress, &Required->SwapEntry);
MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
Required->DoAcquisition = MiSwapInPage;
+ MmUnlockSectionSegment(Segment);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ /*
+ * Map anonymous memory for BSS sections
+ */
+ else if (Entry == 0 &&
+ ((Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) ||
+ Offset.QuadPart >= PAGE_ROUND_UP(Segment->RawLength.QuadPart)))
+ {
+ DPRINT("BSS Page\n");
+ Required->State = 2;
+ Required->Amount = 1;
+ Required->Consumer = MC_USER;
+ Required->DoAcquisition = MiGetOnePage;
MmUnlockSectionSegment(Segment);
return STATUS_MORE_PROCESSING_REQUIRED;
}
@@ -690,6 +738,7 @@
/*
* Write the page to the pagefile
*/
+ DPRINT1("Writing swap entry: %x %x\n", SwapEntry, Page);
Status = MmWriteToSwapPage(SwapEntry, Page);
if (!NT_SUCCESS(Status))
{
@@ -749,15 +798,22 @@
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
if (SwapEntry == MM_WAIT_ENTRY)
{
+ DPRINT1
+ ("SwapEntry is a WAIT, our swap to is %x, State is %x for (%x:%x) on page
%x\n",
+ Required->SwapEntry,
+ Required->State,
+ Process,
+ Address,
+ OurPage);
if (Required->SwapEntry || (Required->State & 2))
{
- MmDeleteRmap(OurPage, Process, Address);
Status = MmCreatePageFileMapping(Process, Address, Required->SwapEntry);
MmSetSavedSwapEntryPage(OurPage, 0);
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
+ MmDeleteRmap(OurPage, Process, Address);
MmDereferencePage(OurPage);
+ MmUnlockSectionSegment(Segment);
KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
- MmUnlockSectionSegment(Segment);
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
DPRINT("XXX Set Event %x\n", Status);
return Status;
@@ -780,37 +836,34 @@
{
Required->State |= 2;
Required->SwapEntry = MmAllocSwapPage();
- if (!Required->SwapEntry) return STATUS_PAGEFILE_QUOTA;
+ if (!Required->SwapEntry)
+ {
+ MmUnlockSectionSegment(Segment);
+ return STATUS_PAGEFILE_QUOTA;
+ }
+ DPRINT1("MiWriteSwapPage (%x -> %x)\n", OurPage,
Required->SwapEntry);
Required->DoAcquisition = MiWriteSwapPage;
MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY);
MmUnlockSectionSegment(Segment);
return STATUS_MORE_PROCESSING_REQUIRED;
}
- else if (!Required->SwapEntry)
- {
+ else
+ {
+ DPRINT1("Out of swap space for page %x\n", OurPage);
MmUnlockSectionSegment(Segment);
return STATUS_PAGEFILE_QUOTA;
}
- MmDeleteRmap(OurPage, Process, Address);
- MmCreatePageFileMapping(Process, Address, Required->SwapEntry);
- MmDereferencePage(OurPage);
- MmUnlockSectionSegment(Segment);
- return STATUS_SUCCESS;
}
else
{
BOOLEAN Dirty = !!MmIsDirtyPageRmap(OurPage);
Required->State |= Dirty;
DPRINT("Public page evicting %x (dirty %d)\n", OurPage, Required->State
& 1);
- if (Dirty)
- {
- DPRINT("Setting segment page dirty\n");
- MiSetPageEntrySectionSegment(Segment, &TotalOffset, DIRTY_SSE(Entry));
- }
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
MmDeleteRmap(OurPage, Process, Address);
- MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
MmDereferencePage(OurPage);
MmUnlockSectionSegment(Segment);
+ KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);
return STATUS_SUCCESS;
}
}
Modified: branches/arty-newcc/ntoskrnl/mm/section/pagefile.c
URL:
http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/mm/section/…
==============================================================================
--- branches/arty-newcc/ntoskrnl/mm/section/pagefile.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/mm/section/pagefile.c [iso-8859-1] Tue Jan 5 16:15:30
2010
@@ -153,24 +153,20 @@
BOOLEAN Dirty)
{
NTSTATUS Status = STATUS_SUCCESS;
- SWAPENTRY Swap;
-
+ BOOLEAN WriteZero = FALSE;
+ SWAPENTRY Swap = MmGetSavedSwapEntryPage(Page);
+
+ MmLockSectionSegment(Segment);
if (Dirty)
{
- DPRINT("Finalize (dirty) Segment %x\n", Segment);
+ DPRINT1("Finalize (dirty) Segment %x Page %x\n", Segment, Page);
DPRINT("Segment->FileObject %x\n", Segment->FileObject);
DPRINT("Segment->Flags %x\n", Segment->Flags);
if (Segment->FileObject && !(Segment->Flags & MM_IMAGE_SEGMENT))
{
- DPRINT("Segment %x FileObject %x\n", Segment, Segment->FileObject,
&Segment);
+ DPRINT1("Segment %x FileObject %x Offset %x\n", Segment,
Segment->FileObject, FileOffset->LowPart);
Status = MiWriteBackPage(Segment->FileObject, FileOffset, PAGE_SIZE, Page);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Write zero to %x:%x %x\n", Segment, FileOffset->LowPart, Page);
- MmLockSectionSegment(Segment);
- MiSetPageEntrySectionSegment(Segment, FileOffset, 0);
- MmUnlockSectionSegment(Segment);
- }
+ WriteZero = NT_SUCCESS(Status);
}
else
{
@@ -185,29 +181,36 @@
}
DPRINT("Status %x\n", Status);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Set Swap entry\n");
- MmLockSectionSegment(Segment);
- MiSetPageEntrySectionSegment(Segment, FileOffset, MAKE_SWAP_SSE(Swap));
- MmUnlockSectionSegment(Segment);
- }
+ WriteZero = NT_SUCCESS(Status);
}
}
else
{
- DPRINT("Write zero to %x:%x (%x)\n", Segment, FileOffset->LowPart, Page);
- MmLockSectionSegment(Segment);
- MiSetPageEntrySectionSegment(Segment, FileOffset, 0);
- MmUnlockSectionSegment(Segment);
+ WriteZero = TRUE;
}
DPRINT("Status %x\n", Status);
+
+ if (WriteZero)
+ {
+ DPRINT1("Setting page entry in segment %x:%x to swap %x\n", Segment,
FileOffset->LowPart, Swap);
+ MiSetPageEntrySectionSegment(Segment, FileOffset, Swap ? MAKE_SWAP_SSE(Swap) : 0);
+ }
+ else
+ {
+ DPRINT1("Setting page entry in segment %x:%x to page %x\n", Segment,
FileOffset->LowPart, Page);
+ MiSetPageEntrySectionSegment
+ (Segment, FileOffset, Page ? (Dirty ? DIRTY_SSE(MAKE_PFN_SSE(Page)) :
MAKE_PFN_SSE(Page)) : 0);
+ }
+
if (NT_SUCCESS(Status))
{
+ DPRINT1("Removing page %x for real\n", Page);
MmSetSavedSwapEntryPage(Page, 0);
MmDereferencePage(Page);
}
+
+ MmUnlockSectionSegment(Segment);
KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE);