ReactOS  0.4.15-dev-3187-ge372f2b
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.html)
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 
34 static 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 
89  PMMPFN Pfn = MiGetPfnEntry(Page);
90  MI_SET_PFN_DELETED(Pfn);
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;
127  Wsle[Index].u1.Free.PreviousFree = (Index - NextFree) & MMWSLE_PREVIOUS_FREE_MASK;
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 
192 static
193 VOID
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 
218 static
219 ULONG
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 
274  PMMPFN Pfn = MiGetPfnEntry(Page);
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 ***********************************************************/
308 extern "C"
309 {
310 
312 VOID
313 NTAPI
315  _Inout_ PMMSUPPORT Vm,
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 
355 VOID
356 NTAPI
358  _Inout_ PMMSUPPORT Vm,
360 {
361  RemoveFromWsList(Vm->VmWorkingSetList, Address);
362 
363  Vm->WorkingSetSize -= PAGE_SIZE;
364 }
365 
367 VOID
368 NTAPI
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
385  MiInsertInWorkingSetList(WorkingSet, (PVOID)PXE_BASE, 0U);
386 #elif _MI_PAGING_LEVELS == 3
387  MiInsertInWorkingSetList(WorkingSet, (PVOID)PPE_BASE, 0U);
388 #elif _MI_PAGING_LEVELS == 2
389  MiInsertInWorkingSetList(WorkingSet, (PVOID)PDE_BASE, 0U);
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 
409 VOID
410 NTAPI
412 {
413  PLIST_ENTRY VmListEntry;
414  PMMSUPPORT Vm = NULL;
415  KIRQL OldIrql;
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;
444  KeAttachProcess(&Process->Pcb);
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  {
481  KeDetachProcess();
482  ExReleaseRundownProtection(&Process->RundownProtect);
483  }
484  }
485 
487 }
488 
489 } // extern "C"
#define MI_IS_PAGE_TABLE_ADDRESS(Address)
Definition: miarm.h:177
ULONG PreviousFree
Definition: mmtypes.h:842
KEVENT MmWorkingSetManagerEvent
Definition: wslist.cpp:20
union _MMPFN::@1746 u1
FORCEINLINE BOOLEAN MI_IS_PROCESS_WORKING_SET(PMMSUPPORT WorkingSet)
Definition: miarm.h:666
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define _Inout_
Definition: ms_sal.h:378
#define MiAddressToPde(x)
Definition: mmx86.c:20
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1536
PFN_NUMBER MmMinimumFreePages
Definition: mminit.c:314
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG_PTR Age
Definition: mmtypes.h:830
_Use_decl_annotations_ VOID NTAPI MiRemoveFromWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address)
Definition: wslist.cpp:357
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RunRef)
static ULONG TrimWsList(PMMWSL WsList)
Definition: wslist.cpp:220
union _MMPTE::@2274 u
MMWSLENTRY e1
Definition: mmtypes.h:855
ULONG FirstDynamic
Definition: mmtypes.h:869
struct _MMWSLE MMWSLE
#define U(x)
Definition: wordpad.c:45
PMMWSL VmWorkingSetList
Definition: mmtypes.h:940
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:154
#define ExAcquireRundownProtection
Definition: ex.h:133
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
VOID NTAPI MmWorkingSetManager(VOID)
Definition: wslist.cpp:411
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
USHORT Modified
Definition: mm.h:349
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:938
GLdouble u1
Definition: glext.h:8308
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
_Use_decl_annotations_ VOID NTAPI MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet)
Definition: wslist.cpp:369
static MMPTE GetPteTemplateForWsList(PMMWSL WsList)
Definition: wslist.cpp:24
USHORT PageLocation
Definition: mm.h:354
#define _Use_decl_annotations_
Definition: ms_sal.h:275
ULONG_PTR Long
Definition: mmtypes.h:854
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
MMWSLE Wsle
Definition: mm.h:423
USHORT PrototypePte
Definition: mm.h:352
ULONG64 Dirty
Definition: mmtypes.h:164
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD(IN PETHREAD Thread)
Definition: miarm.h:1057
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:386
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG BeingTrimmed
Definition: mmtypes.h:903
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define PDE_BASE
Definition: winldr.c:21
PFN_NUMBER MmPlentyFreePages
Definition: mminit.c:322
ULONG_PTR Hashed
Definition: mmtypes.h:828
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
#define PsGetCurrentProcess
Definition: psfuncs.h:17
union _MMWSLE::@2544 u1
unsigned char BOOLEAN
FORCEINLINE VOID MI_MAKE_TRANSITION_PTE(_Out_ PMMPTE NewPte, _In_ PFN_NUMBER Page, _In_ ULONG Protection)
Definition: miarm.h:934
static WCHAR Address[46]
Definition: ping.c:68
#define _In_
Definition: ms_sal.h:308
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1356
MMWSLE_FREE_ENTRY Free
Definition: mmtypes.h:856
PFN_NUMBER Page
Definition: section.c:4923
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
KIRQL OldIrql
Definition: mm.h:1502
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:930
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:260
#define ASSERT(a)
Definition: mode.c:44
union _MMPFN::@1748 u3
_In_ WDFCOLLECTION _In_ ULONG Index
ULONG LastInitializedWsle
Definition: mmtypes.h:873
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_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:238
MMPTE ValidKernelPteLocal
Definition: init.c:33
ULONG64 Valid
Definition: mmtypes.h:150
ULONG MustBeZero
Definition: mmtypes.h:836
static VOID RemoveFromWsList(PMMWSL WsList, PVOID Address)
Definition: wslist.cpp:194
#define MMWSLE_PREVIOUS_FREE_JUMP
Definition: mmtypes.h:844
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
LONG NextFree
Definition: mmtypes.h:845
#define PPE_BASE
ULONG_PTR VirtualPageNumber
Definition: mmtypes.h:831
MMPTE ValidKernelPte
Definition: init.c:29
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
PMMWSLE Wsle
Definition: mmtypes.h:872
static void FreeWsleIndex(PMMWSL WsList, ULONG Index)
Definition: wslist.cpp:34
Definition: mm.h:362
FORCEINLINE VOID MiUnlockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1394
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1000
ULONG_PTR Valid
Definition: mmtypes.h:824
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
ULONG_PTR Long
Definition: mmtypes.h:215
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define PXE_BASE
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1640
FORCEINLINE VOID MiLockWorkingSetShared(_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
Definition: miarm.h:1311
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
ULONG_PTR LockedInMemory
Definition: mmtypes.h:826
ULONG_PTR PteFrame
Definition: mm.h:407
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
PFN_NUMBER Total
Definition: mm.h:432
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1108
ULONG FirstFree
Definition: mmtypes.h:868
static ULONG GetFreeWsleIndex(PMMWSL WsList)
Definition: wslist.cpp:149
#define NULL
Definition: types.h:112
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1549
#define MMWSLE_PREVIOUS_FREE_MASK
Definition: mmtypes.h:843
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD_EXCLUSIVE(_In_ PETHREAD Thread)
Definition: miarm.h:1070
ULONG WsIndex
Definition: mm.h:367
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
FORCEINLINE BOOLEAN MiConvertSharedWorkingSetLockToExclusive(_In_ PETHREAD Thread, _In_ PMMSUPPORT Vm)
Definition: miarm.h:1433
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1033
PMMWSL MmSystemCacheWorkingSetList
Definition: mminit.c:174
unsigned int ULONG
Definition: retypes.h:1
_Use_decl_annotations_ VOID NTAPI MiInsertInWorkingSetList(_Inout_ PMMSUPPORT Vm, _In_ PVOID Address, _In_ ULONG Protection)
Definition: wslist.cpp:314
ULONG_PTR LockedInWs
Definition: mmtypes.h:825
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
ULONG MaximumWorkingSetSize
Definition: mmtypes.h:939
ULONG_PTR Protection
Definition: mmtypes.h:827
ULONG WorkingSetSize
Definition: mmtypes.h:954
ULONG_PTR Direct
Definition: mmtypes.h:829
static ULONG GetNextPageColorForWsList(PMMWSL WsList)
Definition: wslist.cpp:29
ULONG LastEntry
Definition: mmtypes.h:870
#define UL
Definition: tui.h:82
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG64 Accessed
Definition: mmtypes.h:163
base of all file and directory entries
Definition: entries.h:82
Definition: mmtypes.h:834
#define ULONG_MAX
Definition: limits.h:44
ULONG PageFrameNumber
Definition: mmtypes.h:109
union _MMPFN::@1751 u4