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.c... ============================================================================== --- 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.c... ============================================================================== --- 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.h... ============================================================================== --- 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?r... ============================================================================== --- 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.c... ============================================================================== --- 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@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?re... ============================================================================== --- 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/f... ============================================================================== --- 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/p... ============================================================================== --- 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);