ReactOS 0.4.16-dev-88-ga65b6ae
wslist.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD-3-Clause (https://spdx.org/licenses/BSD-3-Clause)
4 * FILE: ntoskrnl/mm/ARM3/wslist.cpp
5 * PURPOSE: Working set list management
6 * PROGRAMMERS: Jérôme Gardou
7 */
8
9/* INCLUDES *******************************************************************/
10#include <ntoskrnl.h>
11
12#define NDEBUG
13#include <debug.h>
14
15#define MODULE_INVOLVED_IN_ARM3
16#include "miarm.h"
17
18/* GLOBALS ********************************************************************/
21
22/* LOCAL FUNCTIONS ************************************************************/
23
25{
27}
28
30{
32}
33
34static void FreeWsleIndex(PMMWSL WsList, ULONG Index)
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}
148
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}
191
192static
193VOID
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}
217
218static
219ULONG
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}
306
307/* GLOBAL FUNCTIONS ***********************************************************/
308extern "C"
309{
310
312VOID
313NTAPI
317 _In_ ULONG Protection)
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}
353
355VOID
356NTAPI
360{
361 RemoveFromWsList(Vm->VmWorkingSetList, Address);
362
363 Vm->WorkingSetSize -= PAGE_SIZE;
364}
365
367VOID
368NTAPI
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}
408
409VOID
410NTAPI
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}
488
489} // extern "C"
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define PDE_BASE
Definition: winldr.c:21
#define U(x)
Definition: wordpad.c:45
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#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
GLdouble u1
Definition: glext.h:8308
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 ULONG_MAX
Definition: limits.h:44
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1103
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1531
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD_EXCLUSIVE(_In_ PETHREAD Thread)
Definition: miarm.h:1065
FORCEINLINE BOOLEAN MI_IS_PROCESS_WORKING_SET(PMMSUPPORT WorkingSet)
Definition: miarm.h:661
PFN_NUMBER MmMinimumFreePages
Definition: mminit.c:314
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
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
PFN_NUMBER MmPlentyFreePages
Definition: mminit.c:322
PMMWSL MmSystemCacheWorkingSetList
Definition: mminit.c:174
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1544
#define MI_IS_PAGE_TABLE_ADDRESS(Address)
Definition: miarm.h:177
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1351
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD(IN PETHREAD Thread)
Definition: miarm.h:1052
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 MI_MAKE_TRANSITION_PTE(_Out_ PMMPTE NewPte, _In_ PFN_NUMBER Page, _In_ ULONG Protection)
Definition: miarm.h:929
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:233
FORCEINLINE VOID MiUnlockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1389
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: ms_sal.h:378
#define _Use_decl_annotations_
Definition: ms_sal.h:275
#define _In_
Definition: ms_sal.h:308
#define MMWSLE_PREVIOUS_FREE_JUMP
Definition: mmtypes.h:847
#define MMWSLE_PREVIOUS_FREE_MASK
Definition: mmtypes.h:846
struct _MMWSLE MMWSLE
@ ActiveAndValid
Definition: mmtypes.h:159
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
#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
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1726
MMPTE ValidKernelPte
Definition: init.c:29
MMPTE ValidKernelPteLocal
Definition: init.c:33
static WCHAR Address[46]
Definition: ping.c:68
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
#define PXE_BASE
#define PPE_BASE
ULONG PFN_NUMBER
Definition: ke.h:9
base of all file and directory entries
Definition: entries.h:83
ULONG PageFrameNumber
Definition: mmtypes.h:109
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT PrototypePte
Definition: mm.h:363
USHORT Modified
Definition: mm.h:360
USHORT PageLocation
Definition: mm.h:365
PFN_NUMBER Total
Definition: mm.h:443
Definition: mm.h:374
MMWSLE Wsle
Definition: mm.h:434
union _MMPFN::@1802 u4
ULONG WsIndex
Definition: mm.h:378
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1797 u1
union _MMPFN::@1799 u3
ULONG_PTR PteFrame
Definition: mm.h:418
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG64 Accessed
Definition: mmtypes.h:163
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2334 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
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
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
Definition: mmtypes.h:838
ULONG PreviousFree
Definition: mmtypes.h:845
ULONG MustBeZero
Definition: mmtypes.h:839
LONG NextFree
Definition: mmtypes.h:848
MMWSLE_FREE_ENTRY Free
Definition: mmtypes.h:859
ULONG_PTR Long
Definition: mmtypes.h:857
MMWSLENTRY e1
Definition: mmtypes.h:858
union _MMWSLE::@2625 u1
ULONG LastEntry
Definition: mmtypes.h:873
ULONG LastInitializedWsle
Definition: mmtypes.h:876
PMMWSLE Wsle
Definition: mmtypes.h:875
ULONG FirstFree
Definition: mmtypes.h:871
ULONG FirstDynamic
Definition: mmtypes.h:872
#define UL
Definition: tui.h:165
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
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
KEVENT MmWorkingSetManagerEvent
Definition: wslist.cpp:20
static ULONG GetFreeWsleIndex(PMMWSL WsList)
Definition: wslist.cpp:149
static ULONG TrimWsList(PMMWSL WsList)
Definition: wslist.cpp:220
_Use_decl_annotations_ VOID NTAPI MiRemoveFromWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address)
Definition: wslist.cpp:357
static void FreeWsleIndex(PMMWSL WsList, ULONG Index)
Definition: wslist.cpp:34
static VOID RemoveFromWsList(PMMWSL WsList, PVOID Address)
Definition: wslist.cpp:194
static MMPTE GetPteTemplateForWsList(PMMWSL WsList)
Definition: wslist.cpp:24
static ULONG GetNextPageColorForWsList(PMMWSL WsList)
Definition: wslist.cpp:29
_Use_decl_annotations_ VOID NTAPI MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet)
Definition: wslist.cpp:369
VOID NTAPI MmWorkingSetManager(VOID)
Definition: wslist.cpp:411
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define PsGetCurrentProcess
Definition: psfuncs.h:17