ReactOS 0.4.15-dev-7918-g2a2556c
wslist.cpp File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include "miarm.h"
Include dependency graph for wslist.cpp:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

static MMPTE GetPteTemplateForWsList (PMMWSL WsList)
 
static ULONG GetNextPageColorForWsList (PMMWSL WsList)
 
static void FreeWsleIndex (PMMWSL WsList, ULONG Index)
 
static ULONG GetFreeWsleIndex (PMMWSL WsList)
 
static VOID RemoveFromWsList (PMMWSL WsList, PVOID Address)
 
static ULONG TrimWsList (PMMWSL WsList)
 
_Use_decl_annotations_ VOID NTAPI MiInsertInWorkingSetList (_Inout_ PMMSUPPORT Vm, _In_ PVOID Address, _In_ ULONG Protection)
 
_Use_decl_annotations_ VOID NTAPI MiRemoveFromWorkingSetList (_Inout_ PMMSUPPORT Vm, _In_ PVOID Address)
 
_Use_decl_annotations_ VOID NTAPI MiInitializeWorkingSetList (_Inout_ PMMSUPPORT WorkingSet)
 
VOID NTAPI MmWorkingSetManager (VOID)
 

Variables

PMMWSL MmWorkingSetList
 
KEVENT MmWorkingSetManagerEvent
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file wslist.cpp.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file wslist.cpp.

Function Documentation

◆ FreeWsleIndex()

static void FreeWsleIndex ( PMMWSL  WsList,
ULONG  Index 
)
static

Definition at line 34 of file wslist.cpp.

35{
36 PMMWSLE Wsle = WsList->Wsle;
37 ULONG& LastEntry = WsList->LastEntry;
38 ULONG& FirstFree = WsList->FirstFree;
39 ULONG& LastInitializedWsle = WsList->LastInitializedWsle;
40
41 /* Erase it now */
42 Wsle[Index].u1.Long = 0;
43
44 if (Index == (LastEntry - 1))
45 {
46 /* We're freeing the last index of our list. */
47 while (Wsle[Index].u1.e1.Valid == 0)
48 Index--;
49
50 /* Should we bother about the Free entries */
51 if (FirstFree < Index)
52 {
53 /* Try getting the index of the last free entry */
54 ASSERT(Wsle[Index + 1].u1.Free.MustBeZero == 0);
55 ULONG PreviousFree = Wsle[Index + 1].u1.Free.PreviousFree;
56 ASSERT(PreviousFree < LastEntry);
57 ULONG LastFree = Index + 1 - PreviousFree;
58#ifdef MMWSLE_PREVIOUS_FREE_JUMP
59 while (Wsle[LastFree].u1.e1.Valid)
60 {
62 LastFree -= MMWSLE_PREVIOUS_FREE_JUMP;
63 }
64#endif
65 /* Update */
66 ASSERT(LastFree >= FirstFree);
67 Wsle[FirstFree].u1.Free.PreviousFree = (Index + 1 - LastFree) & MMWSLE_PREVIOUS_FREE_MASK;
68 Wsle[LastFree].u1.Free.NextFree = 0;
69 }
70 else
71 {
72 /* No more free entries in our array */
73 FirstFree = ULONG_MAX;
74 }
75 /* This is the new size of our array */
76 LastEntry = Index + 1;
77 /* Should we shrink the alloc? */
78 while ((LastInitializedWsle - LastEntry) > (PAGE_SIZE / sizeof(MMWSLE)))
79 {
80 PMMPTE PointerPte = MiAddressToPte(Wsle + LastInitializedWsle - 1);
81 /* We must not free ourself! */
82 ASSERT(MiPteToAddress(PointerPte) != WsList);
83
84 PFN_NUMBER Page = PFN_FROM_PTE(PointerPte);
85
86 {
87 ntoskrnl::MiPfnLockGuard PfnLock;
88
93 }
94
95 PointerPte->u.Long = 0;
96
97 KeInvalidateTlbEntry(Wsle + LastInitializedWsle - 1);
98 LastInitializedWsle -= PAGE_SIZE / sizeof(MMWSLE);
99 }
100 return;
101 }
102
103 if (FirstFree == ULONG_MAX)
104 {
105 /* We're the first one. */
106 FirstFree = Index;
107 Wsle[FirstFree].u1.Free.PreviousFree = (LastEntry - FirstFree) & MMWSLE_PREVIOUS_FREE_MASK;
108 return;
109 }
110
111 /* We must find where to place ourself */
112 ULONG NextFree = FirstFree;
113 ULONG PreviousFree = 0;
114 while (NextFree < Index)
115 {
116 ASSERT(Wsle[NextFree].u1.Free.MustBeZero == 0);
117 if (Wsle[NextFree].u1.Free.NextFree == 0)
118 break;
119 PreviousFree = NextFree;
120 NextFree += Wsle[NextFree].u1.Free.NextFree;
121 }
122
123 if (NextFree < Index)
124 {
125 /* This is actually the last free entry */
126 Wsle[NextFree].u1.Free.NextFree = Index - NextFree;
128 Wsle[FirstFree].u1.Free.PreviousFree = (LastEntry - Index) & MMWSLE_PREVIOUS_FREE_MASK;
129 return;
130 }
131
132 if (PreviousFree == 0)
133 {
134 /* This is the first free */
135 Wsle[Index].u1.Free.NextFree = FirstFree - Index;
136 Wsle[Index].u1.Free.PreviousFree = Wsle[FirstFree].u1.Free.PreviousFree;
137 Wsle[FirstFree].u1.Free.PreviousFree = (FirstFree - Index) & MMWSLE_PREVIOUS_FREE_MASK;
138 FirstFree = Index;
139 return;
140 }
141
142 /* Insert */
143 Wsle[PreviousFree].u1.Free.NextFree = (Index - PreviousFree);
144 Wsle[Index].u1.Free.PreviousFree = (Index - PreviousFree) & MMWSLE_PREVIOUS_FREE_MASK;
145 Wsle[Index].u1.Free.NextFree = NextFree - Index;
146 Wsle[NextFree].u1.Free.PreviousFree = (NextFree - Index) & MMWSLE_PREVIOUS_FREE_MASK;
147}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
GLdouble u1
Definition: glext.h:8308
#define ULONG_MAX
Definition: limits.h:44
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define ASSERT(a)
Definition: mode.c:44
#define MMWSLE_PREVIOUS_FREE_JUMP
Definition: mmtypes.h:847
#define MMWSLE_PREVIOUS_FREE_MASK
Definition: mmtypes.h:846
struct _MMWSLE MMWSLE
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToAddress(_Pte)
Definition: mm.h:116
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
ULONG PFN_NUMBER
Definition: ke.h:9
Definition: mm.h:374
union _MMPFN::@1798 u4
ULONG_PTR PteFrame
Definition: mm.h:418
union _MMPTE::@2330 u
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG PreviousFree
Definition: mmtypes.h:845
LONG NextFree
Definition: mmtypes.h:848
union _MMWSLE::@2621 u1
MMWSLE_FREE_ENTRY Free
Definition: mmtypes.h:859
ULONG_PTR Long
Definition: mmtypes.h:857
ULONG LastEntry
Definition: mmtypes.h:873
ULONG LastInitializedWsle
Definition: mmtypes.h:876
PMMWSLE Wsle
Definition: mmtypes.h:875
ULONG FirstFree
Definition: mmtypes.h:871
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by RemoveFromWsList().

◆ GetFreeWsleIndex()

static ULONG GetFreeWsleIndex ( PMMWSL  WsList)
static

Definition at line 149 of file wslist.cpp.

150{
151 ULONG Index;
152 if (WsList->FirstFree != ULONG_MAX)
153 {
154 Index = WsList->FirstFree;
155 ASSERT(Index < WsList->LastInitializedWsle);
156 MMWSLE_FREE_ENTRY& FreeWsle = WsList->Wsle[Index].u1.Free;
157 ASSERT(FreeWsle.MustBeZero == 0);
158 if (FreeWsle.NextFree != 0)
159 {
160 WsList->FirstFree += FreeWsle.NextFree;
161 WsList->Wsle[WsList->FirstFree].u1.Free.PreviousFree = FreeWsle.PreviousFree;
162 }
163 else
164 {
165 WsList->FirstFree = ULONG_MAX;
166 }
167 }
168 else
169 {
170 Index = WsList->LastEntry++;
171 if (Index >= WsList->LastInitializedWsle)
172 {
173 /* Grow our array */
174 PMMPTE PointerPte = MiAddressToPte(&WsList->Wsle[WsList->LastInitializedWsle]);
175 ASSERT(PointerPte->u.Hard.Valid == 0);
177 {
178 ntoskrnl::MiPfnLockGuard PfnLock;
179
182 }
183
184 WsList->LastInitializedWsle += PAGE_SIZE / sizeof(MMWSLE);
185 }
186 }
187
188 WsList->Wsle[Index].u1.Long = 0;
189 return Index;
190}
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1041
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 Valid
Definition: mmtypes.h:150
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
Definition: mmtypes.h:838
ULONG MustBeZero
Definition: mmtypes.h:839
static MMPTE GetPteTemplateForWsList(PMMWSL WsList)
Definition: wslist.cpp:24
static ULONG GetNextPageColorForWsList(PMMWSL WsList)
Definition: wslist.cpp:29

Referenced by MiInsertInWorkingSetList().

◆ GetNextPageColorForWsList()

static ULONG GetNextPageColorForWsList ( PMMWSL  WsList)
static

Definition at line 29 of file wslist.cpp.

30{
32}
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
PMMWSL MmSystemCacheWorkingSetList
Definition: mminit.c:174
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:233
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by GetFreeWsleIndex().

◆ GetPteTemplateForWsList()

static MMPTE GetPteTemplateForWsList ( PMMWSL  WsList)
static

Definition at line 24 of file wslist.cpp.

25{
27}
MMPTE ValidKernelPte
Definition: init.c:29
MMPTE ValidKernelPteLocal
Definition: init.c:33

Referenced by GetFreeWsleIndex().

◆ MiInitializeWorkingSetList()

_Use_decl_annotations_ VOID NTAPI MiInitializeWorkingSetList ( _Inout_ PMMSUPPORT  WorkingSet)

Definition at line 369 of file wslist.cpp.

370{
371 PMMWSL WsList = WorkingSet->VmWorkingSetList;
372
373 /* Initialize some fields */
374 WsList->FirstFree = ULONG_MAX;
375 WsList->Wsle = reinterpret_cast<PMMWSLE>(WsList + 1);
376 WsList->LastEntry = 0;
377 /* The first page is already allocated */
378 WsList->LastInitializedWsle = (PAGE_SIZE - sizeof(*WsList)) / sizeof(MMWSLE);
379
380 /* Insert the address we already know: our PDE base and the Working Set List */
381 if (MI_IS_PROCESS_WORKING_SET(WorkingSet))
382 {
383 ASSERT(WorkingSet->VmWorkingSetList == MmWorkingSetList);
384#if _MI_PAGING_LEVELS == 4
386#elif _MI_PAGING_LEVELS == 3
388#elif _MI_PAGING_LEVELS == 2
390#endif
391 }
392
393#if _MI_PAGING_LEVELS == 4
394 MiInsertInWorkingSetList(WorkingSet, MiAddressToPpe(WorkingSet->VmWorkingSetList), 0UL);
395#endif
396#if _MI_PAGING_LEVELS >= 3
397 MiInsertInWorkingSetList(WorkingSet, MiAddressToPde(WorkingSet->VmWorkingSetList), 0UL);
398#endif
399 MiInsertInWorkingSetList(WorkingSet, (PVOID)MiAddressToPte(WorkingSet->VmWorkingSetList), 0UL);
400 MiInsertInWorkingSetList(WorkingSet, (PVOID)WorkingSet->VmWorkingSetList, 0UL);
401
402 /* From now on, every added page can be trimmed at any time */
403 WsList->FirstDynamic = WsList->LastEntry;
404
405 /* We can add this to our list */
406 ExInterlockedInsertTailList(&MmWorkingSetExpansionHead, &WorkingSet->WorkingSetExpansionLinks, &MmExpansionLock);
407}
#define PDE_BASE
Definition: winldr.c:21
#define U(x)
Definition: wordpad.c:45
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
FORCEINLINE BOOLEAN MI_IS_PROCESS_WORKING_SET(PMMSUPPORT WorkingSet)
Definition: miarm.h:661
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
#define MiAddressToPde(x)
Definition: mmx86.c:20
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
#define PXE_BASE
#define PPE_BASE
ULONG FirstDynamic
Definition: mmtypes.h:872
#define UL
Definition: tui.h:165
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
_Use_decl_annotations_ VOID NTAPI MiInsertInWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address, _In_ ULONG Protection)
Definition: wslist.cpp:314

Referenced by MmInitializeProcessAddressSpace().

◆ MiInsertInWorkingSetList()

_Use_decl_annotations_ VOID NTAPI MiInsertInWorkingSetList ( _Inout_ PMMSUPPORT  Vm,
_In_ PVOID  Address,
_In_ ULONG  Protection 
)

Definition at line 314 of file wslist.cpp.

318{
319 PMMWSL WsList = Vm->VmWorkingSetList;
320
321 /* Make sure that we are holding the WS lock. */
323
324 PMMPTE PointerPte = MiAddressToPte(Address);
325
326 /* Make sure we are adding a paged-in address */
327 ASSERT(PointerPte->u.Hard.Valid == 1);
328 PMMPFN Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
330
331 /* Shared pages not supported yet */
332 ASSERT(Pfn1->u1.WsIndex == 0);
333 ASSERT(Pfn1->u3.e1.PrototypePte == 0);
334
335 /* Nor are "ROS PFN" */
336 ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
337
338 Pfn1->u1.WsIndex = GetFreeWsleIndex(WsList);
339 MMWSLENTRY& NewWsle = WsList->Wsle[Pfn1->u1.WsIndex].u1.e1;
340 NewWsle.VirtualPageNumber = reinterpret_cast<ULONG_PTR>(Address) >> PAGE_SHIFT;
341 NewWsle.Protection = Protection;
342 NewWsle.Direct = 1;
343 NewWsle.Hashed = 0;
344 NewWsle.LockedInMemory = 0;
345 NewWsle.LockedInWs = 0;
346 NewWsle.Age = 0;
347 NewWsle.Valid = 1;
348
349 Vm->WorkingSetSize += PAGE_SIZE;
350 if (Vm->WorkingSetSize > Vm->PeakWorkingSetSize)
351 Vm->PeakWorkingSetSize = Vm->WorkingSetSize;
352}
#define FALSE
Definition: types.h:117
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1103
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD_EXCLUSIVE(_In_ PETHREAD Thread)
Definition: miarm.h:1065
@ ActiveAndValid
Definition: mmtypes.h:159
static WCHAR Address[46]
Definition: ping.c:68
USHORT PrototypePte
Definition: mm.h:363
USHORT PageLocation
Definition: mm.h:365
union _MMPFN::@1795 u3
ULONG WsIndex
Definition: mm.h:378
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1793 u1
ULONG_PTR Valid
Definition: mmtypes.h:827
ULONG_PTR Direct
Definition: mmtypes.h:832
ULONG_PTR Protection
Definition: mmtypes.h:830
ULONG_PTR LockedInMemory
Definition: mmtypes.h:829
ULONG_PTR Hashed
Definition: mmtypes.h:831
ULONG_PTR VirtualPageNumber
Definition: mmtypes.h:834
ULONG_PTR LockedInWs
Definition: mmtypes.h:828
ULONG_PTR Age
Definition: mmtypes.h:833
MMWSLENTRY e1
Definition: mmtypes.h:858
uint32_t ULONG_PTR
Definition: typedefs.h:65
static ULONG GetFreeWsleIndex(PMMWSL WsList)
Definition: wslist.cpp:149

Referenced by MiInitializeWorkingSetList().

◆ MiRemoveFromWorkingSetList()

_Use_decl_annotations_ VOID NTAPI MiRemoveFromWorkingSetList ( _Inout_ PMMSUPPORT  Vm,
_In_ PVOID  Address 
)

Definition at line 357 of file wslist.cpp.

360{
361 RemoveFromWsList(Vm->VmWorkingSetList, Address);
362
363 Vm->WorkingSetSize -= PAGE_SIZE;
364}
static VOID RemoveFromWsList(PMMWSL WsList, PVOID Address)
Definition: wslist.cpp:194

◆ MmWorkingSetManager()

VOID NTAPI MmWorkingSetManager ( VOID  )

Definition at line 411 of file wslist.cpp.

412{
413 PLIST_ENTRY VmListEntry;
414 PMMSUPPORT Vm = NULL;
416
418
419 for (VmListEntry = MmWorkingSetExpansionHead.Flink;
420 VmListEntry != &MmWorkingSetExpansionHead;
421 VmListEntry = VmListEntry->Flink)
422 {
425
426 /* Don't do anything if we have plenty of free pages. */
428 break;
429
430 Vm = CONTAINING_RECORD(VmListEntry, MMSUPPORT, WorkingSetExpansionLinks);
431
432 /* Let the legacy Mm System space alone */
433 if (Vm == MmGetKernelAddressSpace())
434 continue;
435
437 {
439
440 /* Make sure the process is not terminating abd attach to it */
441 if (!ExAcquireRundownProtection(&Process->RundownProtect))
442 continue;
445 }
446 else
447 {
448 /* FIXME: Session & system space unsupported */
449 continue;
450 }
451
453
454 /* Share-lock for now, we're only reading */
456
457 if (((Vm->WorkingSetSize > Vm->MaximumWorkingSetSize) ||
458 (TrimHard && (Vm->WorkingSetSize > Vm->MinimumWorkingSetSize))) &&
460 {
461 /* We're done */
462 Vm->Flags.BeingTrimmed = 1;
463
464 ULONG Trimmed = TrimWsList(Vm->VmWorkingSetList);
465
466 /* We're done */
467 Vm->WorkingSetSize -= Trimmed * PAGE_SIZE;
468 Vm->Flags.BeingTrimmed = 0;
470 }
471 else
472 {
474 }
475
476 /* Lock again */
478
479 if (Process)
480 {
482 ExReleaseRundownProtection(&Process->RundownProtect);
483 }
484 }
485
487}
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ExReleaseRundownProtection
Definition: ex.h:136
#define ExAcquireRundownProtection
Definition: ex.h:135
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1531
PFN_NUMBER MmMinimumFreePages
Definition: mminit.c:314
PFN_NUMBER MmPlentyFreePages
Definition: mminit.c:322
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1544
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1351
FORCEINLINE VOID MiLockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1306
FORCEINLINE BOOLEAN MiConvertSharedWorkingSetLockToExclusive(_In_ PETHREAD Thread, _In_ PMMSUPPORT Vm)
Definition: miarm.h:1428
FORCEINLINE VOID MiUnlockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1389
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1726
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PFN_NUMBER Total
Definition: mm.h:443
ULONG BeingTrimmed
Definition: mmtypes.h:906
ULONG WorkingSetSize
Definition: mmtypes.h:957
PMMWSL VmWorkingSetList
Definition: mmtypes.h:943
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:933
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:941
ULONG MaximumWorkingSetSize
Definition: mmtypes.h:942
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static ULONG TrimWsList(PMMWSL WsList)
Definition: wslist.cpp:220
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

◆ RemoveFromWsList()

static VOID RemoveFromWsList ( PMMWSL  WsList,
PVOID  Address 
)
static

Definition at line 194 of file wslist.cpp.

195{
196 /* Make sure that we are holding the right locks. */
198
199 PMMPTE PointerPte = MiAddressToPte(Address);
200
201 /* Make sure we are removing a paged-in address */
202 ASSERT(PointerPte->u.Hard.Valid == 1);
203 PMMPFN Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
205
206 /* Shared pages not supported yet */
207 ASSERT(Pfn1->u3.e1.PrototypePte == 0);
208
209 /* Nor are "ROS PFN" */
210 ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
211
212 /* And we should have a valid index here */
213 ASSERT(Pfn1->u1.WsIndex != 0);
214
215 FreeWsleIndex(WsList, Pfn1->u1.WsIndex);
216}
static void FreeWsleIndex(PMMWSL WsList, ULONG Index)
Definition: wslist.cpp:34

Referenced by MiRemoveFromWorkingSetList(), and TrimWsList().

◆ TrimWsList()

static ULONG TrimWsList ( PMMWSL  WsList)
static

Definition at line 220 of file wslist.cpp.

221{
222 /* This should be done under WS lock */
224
225 ULONG Ret = 0;
226
227 /* Walk the array */
228 for (ULONG i = WsList->FirstDynamic; i < WsList->LastEntry; i++)
229 {
230 MMWSLE& Entry = WsList->Wsle[i];
231 if (!Entry.u1.e1.Valid)
232 continue;
233
234 /* Only direct entries for now */
235 ASSERT(Entry.u1.e1.Direct == 1);
236
237 /* Check the PTE */
238 PMMPTE PointerPte = MiAddressToPte(Entry.u1.VirtualAddress);
239
240 /* This must be valid */
241 ASSERT(PointerPte->u.Hard.Valid);
242
243 /* If the PTE was accessed, simply reset and that's the end of it */
244 if (PointerPte->u.Hard.Accessed)
245 {
246 Entry.u1.e1.Age = 0;
247 PointerPte->u.Hard.Accessed = 0;
248 KeInvalidateTlbEntry(Entry.u1.VirtualAddress);
249 continue;
250 }
251
252 /* If the entry is not so old, just age it */
253 if (Entry.u1.e1.Age < 3)
254 {
255 Entry.u1.e1.Age++;
256 continue;
257 }
258
259 if ((Entry.u1.e1.LockedInMemory) || (Entry.u1.e1.LockedInWs))
260 {
261 /* This one is locked. Next time, maybe... */
262 continue;
263 }
264
265 /* FIXME: Invalidating PDEs breaks legacy MMs */
266 if (MI_IS_PAGE_TABLE_ADDRESS(Entry.u1.VirtualAddress))
267 continue;
268
269 /* Please put yourself aside and make place for the younger ones */
270 PFN_NUMBER Page = PFN_FROM_PTE(PointerPte);
271 {
272 ntoskrnl::MiPfnLockGuard PfnLock;
273
275
276 /* Not supported yet */
277 ASSERT(Pfn->u3.e1.PrototypePte == 0);
278 ASSERT(!MI_IS_ROS_PFN(Pfn));
279
280 /* FIXME: Remove this hack when possible */
281 if (Pfn->Wsle.u1.e1.LockedInMemory || (Pfn->Wsle.u1.e1.LockedInWs))
282 {
283 continue;
284 }
285
286 /* We can remove it from the list. Save Protection first */
287 ULONG Protection = Entry.u1.e1.Protection;
288 RemoveFromWsList(WsList, Entry.u1.VirtualAddress);
289
290 /* Dirtify the page, if needed */
291 if (PointerPte->u.Hard.Dirty)
292 Pfn->u3.e1.Modified = 1;
293
294 /* Make this a transition PTE */
295 MI_MAKE_TRANSITION_PTE(PointerPte, Page, Protection);
297
298 /* Drop the share count. This will take care of putting it in the standby or modified list. */
300 }
301
302 Ret++;
303 }
304 return Ret;
305}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MI_IS_PAGE_TABLE_ADDRESS(Address)
Definition: miarm.h:177
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD(IN PETHREAD Thread)
Definition: miarm.h:1052
FORCEINLINE VOID MI_MAKE_TRANSITION_PTE(_Out_ PMMPTE NewPte, _In_ PFN_NUMBER Page, _In_ ULONG Protection)
Definition: miarm.h:929
base of all file and directory entries
Definition: entries.h:83
USHORT Modified
Definition: mm.h:360
MMWSLE Wsle
Definition: mm.h:434
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG64 Accessed
Definition: mmtypes.h:163

Referenced by MmWorkingSetManager().

Variable Documentation

◆ MmWorkingSetList

◆ MmWorkingSetManagerEvent

KEVENT MmWorkingSetManagerEvent

Definition at line 20 of file wslist.cpp.