From f26931379314877f418c060c31493fac435dbd42 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Mon, 27 Sep 2010 21:58:54 +0000 Subject: [PATCH] - Remove MiZeroPage, use MiZeroPhysicalPage instead. They work pretty much the same except the needless raise to DISPATCH_LEVEL. - Get rid of the messed up MiMapPageToZeroInHyperSpace which was hacking into MiMapPagesToZeroInHyperSpace. Now MiMapPagesToZeroInHyperSpace is properly implemented to use chained PFNs, and the MmZeroPageThread code has been modified to correctly use the new mechanism. - Zero page mapping now happens at PASSIVE trough MiMapPAgesToZeroInHyperSpace, not DISPATCH anymore. - More fixes are coming to remove the remaining MiRemoveHeadList and rewrite the zero page loop. Should fix more possible corruptions. svn path=/trunk/; revision=48912 --- reactos/ntoskrnl/cc/copy.c | 13 ++++---- reactos/ntoskrnl/include/internal/mm.h | 10 +----- reactos/ntoskrnl/mm/ARM3/hypermap.c | 28 ++++++++-------- reactos/ntoskrnl/mm/ARM3/pfnlist.c | 1 + reactos/ntoskrnl/mm/balance.c | 8 ++++- reactos/ntoskrnl/mm/freelist.c | 45 +++++++------------------- 6 files changed, 42 insertions(+), 63 deletions(-) diff --git a/reactos/ntoskrnl/cc/copy.c b/reactos/ntoskrnl/cc/copy.c index bcc24387efb..628f1dcbed8 100644 --- a/reactos/ntoskrnl/cc/copy.c +++ b/reactos/ntoskrnl/cc/copy.c @@ -29,6 +29,12 @@ ULONG CcFastReadResourceMiss; /* FUNCTIONS *****************************************************************/ +VOID +NTAPI +MiZeroPhysicalPage( + IN PFN_NUMBER PageFrameIndex +); + VOID NTAPI CcInitCacheZeroPage(VOID) @@ -41,12 +47,7 @@ CcInitCacheZeroPage(VOID) DbgPrint("Can't allocate CcZeroPage.\n"); KeBugCheck(CACHE_MANAGER); } - Status = MiZeroPage(CcZeroPage); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Can't zero out CcZeroPage.\n"); - KeBugCheck(CACHE_MANAGER); - } + MiZeroPhysicalPage(CcZeroPage); } NTSTATUS diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 346d9c08a54..e359749903f 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -1189,7 +1189,7 @@ MiUnmapPageInHyperSpace(IN PEPROCESS Process, PVOID NTAPI -MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages, +MiMapPagesToZeroInHyperSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages); VOID @@ -1208,14 +1208,6 @@ MmCreateHyperspaceMapping(IN PFN_NUMBER Page) return MiMapPageInHyperSpace(HyperProcess, Page, &HyperIrql); } -FORCEINLINE -PVOID -MiMapPageToZeroInHyperSpace(IN PFN_NUMBER Page) -{ - PMMPFN Pfn1 = MiGetPfnEntry(Page); - return MiMapPagesToZeroInHyperSpace(&Pfn1, 1); -} - #define MmDeleteHyperspaceMapping(x) MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql); /* i386/page.c *********************************************************/ diff --git a/reactos/ntoskrnl/mm/ARM3/hypermap.c b/reactos/ntoskrnl/mm/ARM3/hypermap.c index fca9e03929b..cb5cb2f1059 100644 --- a/reactos/ntoskrnl/mm/ARM3/hypermap.c +++ b/reactos/ntoskrnl/mm/ARM3/hypermap.c @@ -112,18 +112,17 @@ MiUnmapPageInHyperSpace(IN PEPROCESS Process, PVOID NTAPI -MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages, +MiMapPagesToZeroInHyperSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages) { MMPTE TempPte; PMMPTE PointerPte; PFN_NUMBER Offset, PageFrameIndex; - PMMPFN Page; // // Sanity checks // - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ASSERT(NumberOfPages != 0); ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1)); @@ -151,19 +150,17 @@ MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages, // PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages; - // - // Write the current PTE - // + /* Choose the correct PTE to use, and which template */ PointerPte += (Offset + 1); TempPte = ValidKernelPte; MI_MAKE_LOCAL_PAGE(&TempPte); // Hyperspace is local! - do + + /* Make sure the list isn't empty and loop it */ + ASSERT(Pfn1 != (PVOID)LIST_HEAD); + while (Pfn1 != (PVOID)LIST_HEAD) { - // - // Get the first page entry and its PFN - // - Page = *Pages++; - PageFrameIndex = MiGetPfnEntryIndex(Page); + /* Get the page index for this PFN */ + PageFrameIndex = MiGetPfnEntryIndex(Pfn1); // // Write the PFN @@ -175,7 +172,10 @@ MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages, // PointerPte--; MI_WRITE_VALID_PTE(PointerPte, TempPte); - } while (--NumberOfPages); + + /* Move to the next PFN */ + Pfn1 = (PMMPFN)Pfn1->u1.Flink; + } // // Return the address @@ -193,7 +193,7 @@ MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, // // Sanity checks // - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ASSERT (NumberOfPages != 0); ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1)); diff --git a/reactos/ntoskrnl/mm/ARM3/pfnlist.c b/reactos/ntoskrnl/mm/ARM3/pfnlist.c index 659adccedd0..025aa7cddf4 100644 --- a/reactos/ntoskrnl/mm/ARM3/pfnlist.c +++ b/reactos/ntoskrnl/mm/ARM3/pfnlist.c @@ -66,6 +66,7 @@ MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex) /* Map in hyperspace, then wipe it using XMMI or MEMSET */ VirtualAddress = MiMapPageInHyperSpace(Process, PageFrameIndex, &OldIrql); + ASSERT(VirtualAddress); KeZeroPages(VirtualAddress, PAGE_SIZE); MiUnmapPageInHyperSpace(Process, VirtualAddress, OldIrql); } diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index 555c7a666db..9ce2dd13e57 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -99,6 +99,12 @@ MmInitializeMemoryConsumer(ULONG Consumer, MiMemoryConsumers[Consumer].Trim = Trim; } +VOID +NTAPI +MiZeroPhysicalPage( + IN PFN_NUMBER PageFrameIndex +); + NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page) @@ -131,7 +137,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page) Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); KeReleaseSpinLock(&AllocationListLock, OldIrql); if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); - MiZeroPage(Page); + MiZeroPhysicalPage(Page); Request->Page = Page; KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); } diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 513a1626335..aea3f0e35f8 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -360,7 +360,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, // Pfn1 = MiGetPfnEntry(Page); ASSERT(Pfn1); - if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPage(Page); + if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPhysicalPage(Page); Pfn1->u3.e1.PageLocation = ActiveAndValid; } @@ -625,25 +625,6 @@ MmAllocPage(ULONG Type) return PfnOffset; } -NTSTATUS -NTAPI -MiZeroPage(PFN_NUMBER Page) -{ - KIRQL Irql; - PVOID TempAddress; - - Irql = KeRaiseIrqlToDpcLevel(); - TempAddress = MiMapPageToZeroInHyperSpace(Page); - if (TempAddress == NULL) - { - return(STATUS_NO_MEMORY); - } - memset(TempAddress, 0, PAGE_SIZE); - MiUnmapPagesInZeroSpace(TempAddress, 1); - KeLowerIrql(Irql); - return(STATUS_SUCCESS); -} - NTSTATUS NTAPI MmZeroPageThreadMain(PVOID Ignored) @@ -653,6 +634,7 @@ MmZeroPageThreadMain(PVOID Ignored) PPHYSICAL_PAGE PageDescriptor; PFN_NUMBER Pfn; ULONG Count; + PVOID ZeroAddress; /* Free initial kernel memory */ //MiFreeInitMemory(); @@ -679,22 +661,19 @@ MmZeroPageThreadMain(PVOID Ignored) while (MmFreePageListHead.Total) { PageDescriptor = MiRemoveHeadList(&MmFreePageListHead); - /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ - KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); Pfn = MiGetPfnEntryIndex(PageDescriptor); - Status = MiZeroPage(Pfn); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); + + PageDescriptor->u1.Flink = LIST_HEAD; + ZeroAddress = MiMapPagesToZeroInHyperSpace(PageDescriptor, 1); + ASSERT(ZeroAddress); + RtlZeroMemory(ZeroAddress, PAGE_SIZE); + MiUnmapPagesInZeroSpace(ZeroAddress, 1); oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - if (NT_SUCCESS(Status)) - { - MiInsertZeroListAtBack(Pfn); - Count++; - } - else - { - MiInsertInListTail(&MmFreePageListHead, PageDescriptor); - PageDescriptor->u3.e1.PageLocation = FreePageList; - } + + MiInsertZeroListAtBack(Pfn); + Count++; } DPRINT("Zeroed %d pages.\n", Count);