diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index c576997f943..fde2bbc926a 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -665,6 +665,7 @@ CcRosMapVacbInKernelSpace( { PFN_NUMBER PageFrameNumber; + MI_SET_USAGE(MI_USAGE_CACHE); Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &PageFrameNumber); if (PageFrameNumber == 0) { @@ -906,6 +907,25 @@ Retry: InsertTailList(&VacbLruListHead, ¤t->VacbLruListEntry); KeReleaseQueuedSpinLock(LockQueueMasterLock, oldIrql); + MI_SET_USAGE(MI_USAGE_CACHE); +#if MI_TRACE_PFNS + if ((SharedCacheMap->FileObject) && (SharedCacheMap->FileObject->FileName.Buffer)) + { + PWCHAR pos; + ULONG len = 0; + pos = wcsrchr(SharedCacheMap->FileObject->FileName.Buffer, '\\'); + if (pos) + { + len = wcslen(pos) * sizeof(WCHAR); + snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos); + } + else + { + snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%wZ", &SharedCacheMap->FileObject->FileName); + } + } +#endif + /* Reference it to allow release */ CcRosVacbIncRefCount(current); diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index d2ead92df1f..32fd7b1146d 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -2,8 +2,6 @@ #include -#define MI_TRACE_PFNS 1 - /* TYPES *********************************************************************/ struct _EPROCESS; @@ -250,45 +248,9 @@ MM_RMAP_ENTRY, *PMM_RMAP_ENTRY; extern ULONG MI_PFN_CURRENT_USAGE; extern CHAR MI_PFN_CURRENT_PROCESS_NAME[16]; #define MI_SET_USAGE(x) MI_PFN_CURRENT_USAGE = x -#define MI_SET_PROCESS2(x) memcpy(MI_PFN_CURRENT_PROCESS_NAME, x, min(sizeof(x), sizeof(MI_PFN_CURRENT_PROCESS_NAME))) -FORCEINLINE -void -MI_SET_PROCESS(PEPROCESS Process) -{ - if (!Process) - MI_SET_PROCESS2("Kernel"); - else if (Process == (PEPROCESS)1) - MI_SET_PROCESS2("Hydra"); - else - MI_SET_PROCESS2(Process->ImageFileName); -} - -FORCEINLINE -void -MI_SET_PROCESS_USTR(PUNICODE_STRING ustr) -{ - PWSTR pos, strEnd; - int i; - - if (!ustr->Buffer || ustr->Length == 0) - { - MI_PFN_CURRENT_PROCESS_NAME[0] = 0; - return; - } - - pos = strEnd = &ustr->Buffer[ustr->Length / sizeof(WCHAR)]; - while ((*pos != L'\\') && (pos > ustr->Buffer)) - pos--; - - if (*pos == L'\\') - pos++; - - for (i = 0; i < sizeof(MI_PFN_CURRENT_PROCESS_NAME) && pos <= strEnd; i++, pos++) - MI_PFN_CURRENT_PROCESS_NAME[i] = (CHAR)*pos; -} +#define MI_SET_PROCESS2(x) memcpy(MI_PFN_CURRENT_PROCESS_NAME, x, 16) #else #define MI_SET_USAGE(x) -#define MI_SET_PROCESS(x) #define MI_SET_PROCESS2(x) #endif @@ -316,9 +278,6 @@ typedef enum _MI_PFN_USAGES MI_USAGE_PFN_DATABASE, MI_USAGE_BOOT_DRIVER, MI_USAGE_INIT_MEMORY, - MI_USAGE_PAGE_FILE, - MI_USAGE_COW, - MI_USAGE_WSLE, MI_USAGE_FREE_PAGE } MI_PFN_USAGES; @@ -399,7 +358,6 @@ typedef struct _MMPFN #if MI_TRACE_PFNS MI_PFN_USAGES PfnUsage; CHAR ProcessName[16]; -#define MI_SET_PFN_PROCESS_NAME(pfn, x) memcpy(pfn->ProcessName, x, min(sizeof(x), sizeof(pfn->ProcessName))) #endif // HACK until WS lists are supported diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index a30e9957874..6df6b7e5385 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -1058,10 +1058,6 @@ VOID NTAPI MiInsertInWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address, _In_ ULONG Protection); -VOID -NTAPI -MiRemoveFromWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address); - // // New ARM3<->RosMM PAGE Architecture // diff --git a/ntoskrnl/mm/ARM3/mminit.c b/ntoskrnl/mm/ARM3/mminit.c index 3c724d8ea3e..0bae38e3e02 100644 --- a/ntoskrnl/mm/ARM3/mminit.c +++ b/ntoskrnl/mm/ARM3/mminit.c @@ -801,7 +801,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock) Pfn1->u3.e1.CacheAttribute = MiNonCached; #if MI_TRACE_PFNS Pfn1->PfnUsage = MI_USAGE_INIT_MEMORY; - MI_SET_PFN_PROCESS_NAME(Pfn1, "Initial PDE"); + memcpy(Pfn1->ProcessName, "Initial PDE", 16); #endif } else @@ -848,7 +848,7 @@ MiBuildPfnDatabaseFromPages(IN PLOADER_PARAMETER_BLOCK LoaderBlock) Pfn2->u3.e1.CacheAttribute = MiNonCached; #if MI_TRACE_PFNS Pfn2->PfnUsage = MI_USAGE_INIT_MEMORY; - MI_SET_PFN_PROCESS_NAME(Pfn2, "Initial PTE"); + memcpy(Pfn1->ProcessName, "Initial PTE", 16); #endif } } diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c index a487d3a1ba2..1ab109e9f65 100644 --- a/ntoskrnl/mm/ARM3/pagfault.c +++ b/ntoskrnl/mm/ARM3/pagfault.c @@ -697,6 +697,16 @@ MiResolveDemandZeroFault(IN PVOID Address, /* Increment demand zero faults */ KeGetCurrentPrcb()->MmDemandZeroCount++; + /* Do we have the lock? */ + if (HaveLock) + { + /* Release it */ + MiReleasePfnLock(OldIrql); + + /* Update performance counters */ + if (Process > HYDRA_PROCESS) Process->NumberOfPrivatePages++; + } + /* Zero the page if need be */ if (NeedZero) MiZeroPfn(PageFrameNumber); @@ -735,23 +745,6 @@ MiResolveDemandZeroFault(IN PVOID Address, ASSERT(Pfn1->u3.e1.PrototypePte == 0); } - /* Add the page to our working set, if it's not a proto PTE */ - if ((Process > HYDRA_PROCESS) && (PointerPte == MiAddressToPte(Address))) - { - /* FIXME: Also support session VM scenario */ - MiInsertInWorkingSetList(&Process->Vm, Address, Protection); - } - - /* Do we have the lock? */ - if (HaveLock) - { - /* Release it */ - MiReleasePfnLock(OldIrql); - - /* Update performance counters */ - if (Process > HYDRA_PROCESS) Process->NumberOfPrivatePages++; - } - // // It's all good now // @@ -906,9 +899,6 @@ MiResolvePageFileFault(_In_ BOOLEAN StoreInstruction, ASSERT(CurrentProcess > HYDRA_PROCESS); ASSERT(*OldIrql != MM_NOIRQL); - MI_SET_USAGE(MI_USAGE_PAGE_FILE); - MI_SET_PROCESS(CurrentProcess); - /* We must hold the PFN lock */ MI_ASSERT_PFN_LOCK_HELD(); @@ -969,9 +959,6 @@ MiResolvePageFileFault(_In_ BOOLEAN StoreInstruction, KeSetEvent(Pfn1->u1.Event, IO_NO_INCREMENT, FALSE); } - /* And we can insert this into the working set */ - MiInsertInWorkingSetList(&CurrentProcess->Vm, FaultingAddress, Protection); - return Status; } @@ -989,8 +976,6 @@ MiResolveTransitionFault(IN BOOLEAN StoreInstruction, PMMPFN Pfn1; MMPTE TempPte; PMMPTE PointerToPteForProtoPage; - ULONG Protection; - DPRINT("Transition fault on 0x%p with PTE 0x%p in process %s\n", FaultingAddress, PointerPte, CurrentProcess->ImageFileName); @@ -1084,9 +1069,8 @@ MiResolveTransitionFault(IN BOOLEAN StoreInstruction, ASSERT(PointerPte->u.Hard.Valid == 0); ASSERT(PointerPte->u.Trans.Prototype == 0); ASSERT(PointerPte->u.Trans.Transition == 1); - Protection = TempPte.u.Trans.Protection; TempPte.u.Long = (PointerPte->u.Long & ~0xFFF) | - (MmProtectToPteMask[Protection]) | + (MmProtectToPteMask[PointerPte->u.Trans.Protection]) | MiDetermineUserGlobalPteMask(PointerPte); /* Is the PTE writeable? */ @@ -1106,10 +1090,6 @@ MiResolveTransitionFault(IN BOOLEAN StoreInstruction, /* Write the valid PTE */ MI_WRITE_VALID_PTE(PointerPte, TempPte); - /* If this was a user fault, add it to the working set */ - if (CurrentProcess > HYDRA_PROCESS) - MiInsertInWorkingSetList(&CurrentProcess->Vm, FaultingAddress, Protection); - /* Return success */ return STATUS_PAGE_FAULT_TRANSITION; } @@ -1230,9 +1210,6 @@ MiResolveProtoPteFault(IN BOOLEAN StoreInstruction, ASSERT(TempPte.u.Hard.Valid == 1); ProtoPageFrameIndex = PFN_FROM_PTE(&TempPte); - MI_SET_USAGE(MI_USAGE_COW); - MI_SET_PROCESS(Process); - /* Get a new page for the private copy */ if (Process > HYDRA_PROCESS) Color = MI_GET_NEXT_PROCESS_COLOR(Process); @@ -1268,13 +1245,6 @@ MiResolveProtoPteFault(IN BOOLEAN StoreInstruction, /* And finally, write the valid PTE */ MI_WRITE_VALID_PTE(PointerPte, PteContents); - /* Add the page to our working set */ - if (Process > HYDRA_PROCESS) - { - /* FIXME: Also support session VM scenario */ - MiInsertInWorkingSetList(&Process->Vm, Address, Protection); - } - /* The caller expects us to release the PFN lock */ MiReleasePfnLock(OldIrql); return Status; @@ -2235,15 +2205,11 @@ UserFault: { PFN_NUMBER PageFrameIndex, OldPageFrameIndex; PMMPFN Pfn1; - ProtectionCode = TempPte.u.Soft.Protection; LockIrql = MiAcquirePfnLock(); ASSERT(MmAvailablePages > 0); - MI_SET_USAGE(MI_USAGE_COW); - MI_SET_PROCESS(CurrentProcess); - /* Allocate a new page and copy it */ PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(CurrentProcess)); OldPageFrameIndex = PFN_FROM_PTE(&TempPte); @@ -2265,9 +2231,6 @@ UserFault: MI_WRITE_VALID_PTE(PointerPte, TempPte); - /* We can now add it to our working set */ - MiInsertInWorkingSetList(&CurrentProcess->Vm, Address, ProtectionCode); - MiReleasePfnLock(LockIrql); /* Return the status */ @@ -2384,7 +2347,6 @@ UserFault: TempPte.u.Soft.Protection = ProtectionCode; MI_WRITE_INVALID_PTE(PointerPte, TempPte); } - ProtectionCode = PointerPte->u.Soft.Protection; /* Lock the PFN database since we're going to grab a page */ OldIrql = MiAcquirePfnLock(); @@ -2422,6 +2384,9 @@ UserFault: /* One more demand-zero fault */ KeGetCurrentPrcb()->MmDemandZeroCount++; + /* And we're done with the lock */ + MiReleasePfnLock(OldIrql); + /* Fault on user PDE, or fault on user PTE? */ if (PointerPte <= MiHighestUserPte) { @@ -2448,12 +2413,6 @@ UserFault: Pfn1 = MI_PFN_ELEMENT(PageFrameIndex); ASSERT(Pfn1->u1.Event == NULL); - /* We can now insert it into the working set */ - MiInsertInWorkingSetList(&CurrentProcess->Vm, Address, ProtectionCode); - - /* And we're done with the lock */ - MiReleasePfnLock(OldIrql); - /* Demand zero */ ASSERT(KeGetCurrentIrql() <= APC_LEVEL); MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread); diff --git a/ntoskrnl/mm/ARM3/pfnlist.c b/ntoskrnl/mm/ARM3/pfnlist.c index 866a29cd15f..b039a5181a2 100644 --- a/ntoskrnl/mm/ARM3/pfnlist.c +++ b/ntoskrnl/mm/ARM3/pfnlist.c @@ -254,8 +254,8 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry) ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET); Entry->PfnUsage = MI_PFN_CURRENT_USAGE; memcpy(Entry->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16); - MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET; - MI_SET_PROCESS2("Not Set"); +// MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET; +// memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16); #endif } @@ -459,11 +459,11 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex, MiDecrementAvailablePages(); #if MI_TRACE_PFNS - ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET); + //ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET); Pfn1->PfnUsage = MI_PFN_CURRENT_USAGE; memcpy(Pfn1->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16); - MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET; - MI_SET_PROCESS2("Not Set"); + //MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET; + //memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16); #endif /* Return the page */ @@ -937,8 +937,9 @@ MiInsertPageInList(IN PMMPFNLIST ListHead, ColorHead->Count++; #if MI_TRACE_PFNS - ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET); + //ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET); Pfn1->PfnUsage = MI_USAGE_FREE_PAGE; + MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET; RtlZeroMemory(Pfn1->ProcessName, 16); #endif } diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c index 2e4d9029d36..ab01d902686 100644 --- a/ntoskrnl/mm/ARM3/procsup.c +++ b/ntoskrnl/mm/ARM3/procsup.c @@ -6,8 +6,6 @@ * PROGRAMMERS: ReactOS Portable Systems Group */ -#define GROW_WSLE 1 - /* INCLUDES *******************************************************************/ #include @@ -864,34 +862,18 @@ MiGetFirstFreeWsleIndex(_Inout_ PMMSUPPORT Vm) if (WsList->LastEntry == WsList->LastInitializedWsle) { /* We must grow our array. Allocate a new page */ - PVOID Address = &WsList->Wsle[WsList->LastInitializedWsle + 1]; - PMMPTE PointerPte = MiAddressToPte(Address); + PMMPTE PointerPte = MiAddressToPte(&WsList->Wsle[WsList->LastInitializedWsle + 1]); MMPTE TempPte; - - MI_SET_USAGE(MI_USAGE_WSLE); - MI_SET_PROCESS(PsGetCurrentProcess()); - - /* We must be at page boundary */ - ASSERT(Address == ALIGN_DOWN_POINTER_BY(Address, PAGE_SIZE)); - PFN_NUMBER PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR()); MiInitializePfn(PageFrameIndex, PointerPte, TRUE); - - TempPte = ValidKernelPteLocal; - TempPte.u.Hard.PageFrameNumber = PageFrameIndex; + MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, MM_READWRITE, PageFrameIndex); MI_WRITE_VALID_PTE(PointerPte, TempPte); WsList->LastInitializedWsle += PAGE_SIZE / sizeof(MMWSLE); - /* Make sure we are staying on the same page */ - ASSERT(Address == ALIGN_DOWN_POINTER_BY(&WsList->Wsle[WsList->LastInitializedWsle], PAGE_SIZE)); - /* We must insert this page in our working set ! */ MiInsertInWorkingSetList(Vm, &WsList->Wsle[WsList->LastInitializedWsle], MM_READWRITE); - - /* Now the last entry is the tail of our WSLE array */ - ASSERT(WsList->Wsle[WsList->LastEntry].u1.e1.VirtualPageNumber == ((ULONG_PTR)&WsList->Wsle[WsList->LastInitializedWsle]) >> PAGE_SHIFT); } /* At this point we must be good to go */ @@ -927,26 +909,18 @@ MiGetFirstFreeWsleIndex(_Inout_ PMMSUPPORT Vm) VOID NTAPI -MiInsertInWorkingSetList( - _Inout_ PMMSUPPORT Vm, - _In_ PVOID Address, - _In_ ULONG Protection) +MiInsertInWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address, _In_ ULONG Protection) { ULONG WsIndex = MiGetFirstFreeWsleIndex(Vm); PMMWSLE WsleEntry = &Vm->VmWorkingSetList->Wsle[WsIndex]; PMMPTE PointerPte = MiAddressToPte(Address); - PMMPFN Pfn1; + PMMPFN Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte)); /* Make sure we got a rounded address */ Address = ALIGN_DOWN_POINTER_BY(Address, PAGE_SIZE); - /* Make sure we are locking the right things */ + /* Make sure we are locking the right thing */ ASSERT(MM_ANY_WS_LOCK_HELD(PsGetCurrentThread())); - MI_ASSERT_PFN_LOCK_HELD(); - - /* Make sure we are adding a paged-in address */ - ASSERT(PointerPte->u.Hard.Valid == 1); - Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte)); /* The Pfn must be an active one */ ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid); @@ -957,11 +931,6 @@ MiInsertInWorkingSetList( /* Shared pages not supported yet */ ASSERT(Pfn1->u1.WsIndex == 0); - ASSERT(Pfn1->u3.e1.PrototypePte == 0); - - /* Nor are "ROS PFN" */ - ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE); - WsleEntry->u1.e1.Direct = 1; Pfn1->u1.WsIndex = WsIndex; @@ -972,177 +941,6 @@ MiInsertInWorkingSetList( Vm->PeakWorkingSetSize = Vm->WorkingSetSize; } -static -void -MiShrinkWorkingSet(_Inout_ PMMSUPPORT Vm) -{ - PMMWSL WsList = Vm->VmWorkingSetList; - ULONG LastValid = WsList->LastEntry; - - while(WsList->Wsle[LastValid].u1.e1.Valid == 0) - { - LastValid--; - } - - if (LastValid != WsList->LastEntry) - { - /* There was a hole behind us. Handle this */ - PMMWSLE NextFree = &WsList->Wsle[LastValid + 1]; - if (NextFree->u1.Free.PreviousFree == MMWSLE_PREVIOUS_FREE_INVALID) - { - /* This was actually our first free entry. */ - ASSERT(WsList->FirstFree == LastValid + 1); - WsList->FirstFree = MMWSLE_NEXT_FREE_INVALID; - } - else - { - /* The previous one is now the last in the queue */ - PMMWSLE PreviousFree = &WsList->Wsle[NextFree->u1.Free.PreviousFree]; - - ASSERT(PreviousFree->u1.Free.MustBeZero == 0); - PreviousFree->u1.Free.NextFree = MMWSLE_NEXT_FREE_INVALID; - } - - /* Nuke everyone */ - RtlZeroMemory(&WsList->Wsle[LastValid + 1], (WsList->LastEntry - LastValid) * sizeof(MMWSLE)); - WsList->LastEntry = LastValid; - } - - if (LastValid < WsList->FirstDynamic) - { - /* Do not mess around with the protected ones */ - return; - } - - /* See if we should shrink our array */ - if (LastValid == (WsList->LastInitializedWsle - (PAGE_SIZE / sizeof(MMWSLE)) + 1)) - { - PVOID WsleArrayQueue = ALIGN_DOWN_POINTER_BY(&WsList->Wsle[LastValid], PAGE_SIZE); - PEPROCESS Process = MmGetAddressSpaceOwner(Vm); - - ASSERT(WsList->Wsle[WsList->LastEntry].u1.e1.VirtualPageNumber == ((ULONG_PTR)WsleArrayQueue) >> PAGE_SHIFT); - - /* Kernel address space not supported yet */ - ASSERT(Process != NULL); - - /* Nuke the PTE. This will remove the virtual address from the working set */ - MiDeletePte(MiAddressToPte(WsleArrayQueue), WsleArrayQueue, Process, NULL); - } -} - -VOID -NTAPI -MiRemoveFromWorkingSetList( - _Inout_ PMMSUPPORT Vm, - _In_ PVOID Address) -{ - PMMWSL WsList = Vm->VmWorkingSetList; - ULONG WsIndex; - PMMWSLE WsleEntry; - PMMPTE PointerPte = MiAddressToPte(Address); - PMMPFN Pfn1; - - /* Make sure we got a rounded address */ - Address = ALIGN_DOWN_POINTER_BY(Address, PAGE_SIZE); - - /* Make sure we are locking the right things */ - ASSERT(MM_ANY_WS_LOCK_HELD(PsGetCurrentThread())); - MI_ASSERT_PFN_LOCK_HELD(); - - /* Make sure we are removing a paged-in address */ - ASSERT(PointerPte->u.Hard.Valid == 1); - Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte)); - - /* The Pfn must be an active one */ - ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid); - - WsIndex = Pfn1->u1.WsIndex; - WsleEntry = &Vm->VmWorkingSetList->Wsle[WsIndex]; - - /* Shared page not handled yet */ - ASSERT(Pfn1->u3.e1.PrototypePte == 0); - ASSERT(WsleEntry->u1.e1.Direct == 1); - /* Nor are "ROS PFN" */ - ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE); - - /* Some sanity checks */ - ASSERT(WsIndex >= WsList->FirstDynamic); - ASSERT(WsIndex <= WsList->LastEntry); - ASSERT(WsIndex <= WsList->LastInitializedWsle); - ASSERT(WsleEntry->u1.e1.Valid == 1); - ASSERT(WsleEntry->u1.e1.VirtualPageNumber == ((ULONG_PTR)Address) >> PAGE_SHIFT); - - /* Let this go */ - Pfn1->u1.WsIndex = 0; - - /* Nuke it */ - WsleEntry->u1.Long = 0; - - /* Insert our entry into the free list */ - if (WsIndex == WsList->LastEntry) - { - /* Let's shrink the active list */ - WsList->LastEntry--; - MiShrinkWorkingSet(Vm); - } - else if (WsList->FirstFree > WsList->LastEntry) - { - /* We are the first free entry to be inserted */ - WsList->FirstFree = WsIndex; - WsleEntry->u1.Free.PreviousFree = MMWSLE_PREVIOUS_FREE_INVALID; - WsleEntry->u1.Free.NextFree = MMWSLE_NEXT_FREE_INVALID; - } - else - { - /* Keep this sorted */ - PMMWSLE NextFree = &WsList->Wsle[WsList->FirstFree]; - PMMWSLE PreviousFree = NULL; - - ASSERT(NextFree->u1.Free.MustBeZero == 0); - - while (NextFree < WsleEntry) - { - PreviousFree = NextFree; - if (NextFree->u1.Free.NextFree != MMWSLE_NEXT_FREE_INVALID) - { - NextFree = &WsList->Wsle[NextFree->u1.Free.NextFree]; - ASSERT(NextFree->u1.Free.MustBeZero == 0); - } - else - { - NextFree = NULL; - break; - } - } - - ASSERT(PreviousFree || NextFree); - - if (PreviousFree) - { - ASSERT((NextFree != NULL) || (PreviousFree->u1.Free.NextFree == MMWSLE_NEXT_FREE_INVALID)); - PreviousFree->u1.Free.NextFree = WsIndex; - WsleEntry->u1.Free.PreviousFree = PreviousFree - WsList->Wsle; - } - else - { - WsleEntry->u1.Free.PreviousFree = MMWSLE_PREVIOUS_FREE_INVALID; - ASSERT(NextFree->u1.Free.PreviousFree == MMWSLE_PREVIOUS_FREE_INVALID); - WsList->FirstFree = WsIndex; - } - - if (NextFree) - { - NextFree->u1.Free.PreviousFree = WsIndex; - WsleEntry->u1.Free.NextFree = NextFree - WsList->Wsle; - } - else - { - WsleEntry->u1.Free.NextFree = MMWSLE_NEXT_FREE_INVALID; - } - } - - Vm->WorkingSetSize -= PAGE_SIZE; -} VOID NTAPI diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c index 58e4c3057b2..d414b1f6b43 100644 --- a/ntoskrnl/mm/ARM3/sysldr.c +++ b/ntoskrnl/mm/ARM3/sysldr.c @@ -188,7 +188,14 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr, /* Some debug stuff */ MI_SET_USAGE(MI_USAGE_DRIVER_PAGE); #if MI_TRACE_PFNS - MI_SET_PROCESS_USTR(FileName); + if (FileName->Buffer) + { + PWCHAR pos = NULL; + ULONG len = 0; + pos = wcsrchr(FileName->Buffer, '\\'); + len = wcslen(pos) * sizeof(WCHAR); + if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos); + } #endif /* Grab a page */ diff --git a/ntoskrnl/mm/ARM3/virtual.c b/ntoskrnl/mm/ARM3/virtual.c index 630afc5c990..f0ab5d08f7b 100644 --- a/ntoskrnl/mm/ARM3/virtual.c +++ b/ntoskrnl/mm/ARM3/virtual.c @@ -503,9 +503,6 @@ MiDeletePte(IN PMMPTE PointerPte, } else { - /* Remove this address from the WS list */ - MiRemoveFromWorkingSetList(&CurrentProcess->Vm, VirtualAddress); - /* Make sure the saved PTE address is valid */ if ((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) != PointerPte) { @@ -2306,15 +2303,13 @@ MiProtectVirtualMemory(IN PEPROCESS Process, { KIRQL OldIrql = MiAcquirePfnLock(); - /* Remove this from the working set */ - MiRemoveFromWorkingSetList(AddressSpace, MiPteToAddress(PointerPte)); - /* Mark the PTE as transition and change its protection */ PteContents.u.Hard.Valid = 0; PteContents.u.Soft.Transition = 1; PteContents.u.Trans.Protection = ProtectionMask; /* Decrease PFN share count and write the PTE */ MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&PteContents)); + // FIXME: remove the page from the WS MI_WRITE_INVALID_PTE(PointerPte, PteContents); #ifdef CONFIG_SMP // FIXME: Should invalidate entry in every CPU TLB @@ -2452,10 +2447,8 @@ MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, VOID NTAPI -MiProcessValidPteList( - _Inout_ PMMSUPPORT Vm, - _Inout_ PMMPTE *ValidPteList, - _In_ ULONG Count) +MiProcessValidPteList(IN PMMPTE *ValidPteList, + IN ULONG Count) { KIRQL OldIrql; ULONG i; @@ -2475,11 +2468,6 @@ MiProcessValidPteList( TempPte = *ValidPteList[i]; ASSERT(TempPte.u.Hard.Valid == 1); - // - // We can now remove this addres from the working set - // - MiRemoveFromWorkingSetList(Vm, MiPteToAddress(ValidPteList[i])); - // // Get the PFN entry for the page itself, and then for its page table // @@ -2521,6 +2509,7 @@ MiDecommitPages(IN PVOID StartingAddress, ULONG CommitReduction = 0; PMMPTE ValidPteList[256]; ULONG PteCount = 0; + PMMPFN Pfn1; MMPTE PteContents; PETHREAD CurrentThread = PsGetCurrentThread(); @@ -2552,10 +2541,10 @@ MiDecommitPages(IN PVOID StartingAddress, // such, and does not flush the entire TLB all the time, but right // now we have bigger problems to worry about than TLB flushing. // - PointerPde = MiPteToPde(PointerPte); + PointerPde = MiAddressToPde(StartingAddress); if (PteCount) { - MiProcessValidPteList(&Process->Vm, ValidPteList, PteCount); + MiProcessValidPteList(ValidPteList, PteCount); PteCount = 0; } @@ -2590,13 +2579,21 @@ MiDecommitPages(IN PVOID StartingAddress, //Process->NumberOfPrivatePages--; if (PteContents.u.Hard.Valid) { + // + // It's valid. At this point make sure that it is not a ROS + // PFN. Also, we don't support ProtoPTEs in this code path. + // + Pfn1 = MiGetPfnEntry(PteContents.u.Hard.PageFrameNumber); + ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE); + ASSERT(Pfn1->u3.e1.PrototypePte == FALSE); + // // Flush any pending PTEs that we had not yet flushed, if our // list has gotten too big, then add this PTE to the flush list. // if (PteCount == 256) { - MiProcessValidPteList(&Process->Vm, ValidPteList, PteCount); + MiProcessValidPteList(ValidPteList, PteCount); PteCount = 0; } ValidPteList[PteCount++] = PointerPte; @@ -2626,7 +2623,7 @@ MiDecommitPages(IN PVOID StartingAddress, // This used to be a zero PTE and it no longer is, so we must add a // reference to the pagetable. // - MiIncrementPageTableReferences(MiPteToAddress(PointerPte)); + MiIncrementPageTableReferences(StartingAddress); // // Next, we account for decommitted PTEs and make the PTE as such @@ -2636,16 +2633,17 @@ MiDecommitPages(IN PVOID StartingAddress, } // - // Move to the next PTE + // Move to the next PTE and the next address // PointerPte++; + StartingAddress = (PVOID)((ULONG_PTR)StartingAddress + PAGE_SIZE); } // // Flush any dangling PTEs from the loop in the last page table, and then // release the working set and return the commit reduction accounting. // - if (PteCount) MiProcessValidPteList(&Process->Vm, ValidPteList, PteCount); + if (PteCount) MiProcessValidPteList(ValidPteList, PteCount); MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread); return CommitReduction; } diff --git a/ntoskrnl/mm/freelist.c b/ntoskrnl/mm/freelist.c index 80447593ecd..93d9bbd9f59 100644 --- a/ntoskrnl/mm/freelist.c +++ b/ntoskrnl/mm/freelist.c @@ -574,21 +574,6 @@ MmAllocPage(ULONG Type) OldIrql = MiAcquirePfnLock(); -#if MI_TRACE_PFNS - switch(Type) - { - case MC_CACHE: - case MC_SYSTEM: - MI_SET_USAGE(MI_USAGE_CACHE); - break; - case MC_USER: - MI_SET_USAGE(MI_USAGE_SECTION); - break; - default: - ASSERT(FALSE); - } -#endif - PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR()); if (!PfnOffset) { diff --git a/ntoskrnl/mm/i386/page.c b/ntoskrnl/mm/i386/page.c index f8337dadc26..6b5ac1e8353 100644 --- a/ntoskrnl/mm/i386/page.c +++ b/ntoskrnl/mm/i386/page.c @@ -264,10 +264,6 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create) MI_WRITE_INVALID_PTE(PointerPde, DemandZeroPde); // Tiny HACK: Parameter 1 is the architecture specific FaultCode for an access violation (i.e. page is present) - - /* Lock the working set, as this will add this address to it */ - MiLockProcessWorkingSetUnsafe(Process, PsGetCurrentThread()); - Status = MiDispatchFault(0x1, Pt, PointerPde, @@ -279,8 +275,6 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create) DBG_UNREFERENCED_LOCAL_VARIABLE(Status); ASSERT(KeAreAllApcsDisabled() == TRUE); ASSERT(PointerPde->u.Hard.Valid == 1); - - MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread()); } return (PULONG)MiAddressToPte(Address); } diff --git a/ntoskrnl/mm/marea.c b/ntoskrnl/mm/marea.c index a68adecd9be..d953f422f96 100644 --- a/ntoskrnl/mm/marea.c +++ b/ntoskrnl/mm/marea.c @@ -331,16 +331,13 @@ MmFreeMemoryArea( ASSERT(AddressSpace != MmGetKernelAddressSpace()); if (MiQueryPageTableReferences((PVOID)Address) == 0) { - KIRQL OldIrql; /* No PTE relies on this PDE. Release it */ - MiLockProcessWorkingSet(Process, PsGetCurrentThread()); - OldIrql = MiAcquirePfnLock(); + KIRQL OldIrql = MiAcquirePfnLock(); PMMPDE PointerPde = MiAddressToPde(Address); ASSERT(PointerPde->u.Hard.Valid == 1); MiDeletePte(PointerPde, MiPdeToPte(PointerPde), Process, NULL); ASSERT(PointerPde->u.Hard.Valid == 0); MiReleasePfnLock(OldIrql); - MiUnlockProcessWorkingSet(Process, PsGetCurrentThread()); } } #endif diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index 0825d4ecb49..ce63e796a3d 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -1163,6 +1163,8 @@ MiReadPage(PMEMORY_AREA MemoryArea, * Allocate a page, this is rather complicated by the possibility * we might have to move other things out of memory */ + MI_SET_USAGE(MI_USAGE_SECTION); + MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName); Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page); if (!NT_SUCCESS(Status)) { @@ -1622,6 +1624,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart) && (Section->AllocationAttributes & SEC_IMAGE)))) { + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); if (!NT_SUCCESS(Status)) { @@ -1702,6 +1707,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, MmUnlockSectionSegment(Segment); MmUnlockAddressSpace(AddressSpace); + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); if (!NT_SUCCESS(Status)) { @@ -1870,6 +1878,9 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace, /* * Allocate a page */ + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage); if (!NT_SUCCESS(Status)) {