ReactOS  r73918
freelist.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: ntoskrnl/mm/freelist.c
5  * PURPOSE: Handle the list of free physical pages
6  *
7  * PROGRAMMERS: David Welch (welch@cwcom.net)
8  * Robert Bergkvist
9  */
10 
11 /* INCLUDES ****************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 #define MODULE_INVOLVED_IN_ARM3
18 #include "ARM3/miarm.h"
19 
20 #define ASSERT_IS_ROS_PFN(x) ASSERT(MI_IS_ROS_PFN(x) == TRUE);
21 
22 /* GLOBALS ****************************************************************/
23 
25 
29 
37 
39 
40 /* FUNCTIONS *************************************************************/
41 
42 VOID
43 NTAPI
45 {
46  PVOID Bitmap;
47 
48  /* Allocate enough buffer for the PFN bitmap and align it on 32-bits */
50  (((MmHighestPhysicalPage + 1) + 31) / 32) * 4,
51  TAG_MM);
52  ASSERT(Bitmap);
53 
54  /* Initialize it and clear all the bits to begin with */
55  RtlInitializeBitMap(&MiUserPfnBitMap,
56  Bitmap,
58  RtlClearAllBits(&MiUserPfnBitMap);
59 }
60 
62 NTAPI
64 {
66  KIRQL OldIrql;
67 
68  /* Find the first user page */
70  Position = RtlFindSetBits(&MiUserPfnBitMap, 1, 0);
72  if (Position == 0xFFFFFFFF) return 0;
73 
74  /* Return it */
75  ASSERT(Position != 0);
77  return Position;
78 }
79 
80 VOID
81 NTAPI
83 {
84  KIRQL OldIrql;
85 
86  /* Set the page as a user page */
87  ASSERT(Pfn != 0);
89  ASSERT(!RtlCheckBit(&MiUserPfnBitMap, (ULONG)Pfn));
91  RtlSetBit(&MiUserPfnBitMap, (ULONG)Pfn);
93 }
94 
96 NTAPI
98 {
100  KIRQL OldIrql;
101 
102  /* Find the next user page */
104  Position = RtlFindSetBits(&MiUserPfnBitMap, 1, (ULONG)PreviousPfn + 1);
106  if (Position == 0xFFFFFFFF) return 0;
107 
108  /* Return it */
109  ASSERT(Position != 0);
110  ASSERT_IS_ROS_PFN(MiGetPfnEntry(Position));
111  return Position;
112 }
113 
114 VOID
115 NTAPI
117 {
118  KIRQL OldIrql;
119 
120  /* Unset the page as a user page */
121  ASSERT(Page != 0);
123  ASSERT(RtlCheckBit(&MiUserPfnBitMap, (ULONG)Page));
125  RtlClearBit(&MiUserPfnBitMap, (ULONG)Page);
127 }
128 
129 BOOLEAN
130 NTAPI
132 {
133  /* Must be a free or zero page, with no references, linked */
134  return ((Pfn1->u3.e1.PageLocation <= StandbyPageList) &&
135  (Pfn1->u1.Flink) &&
136  (Pfn1->u2.Blink) &&
137  !(Pfn1->u3.e2.ReferenceCount));
138 }
139 
140 BOOLEAN
141 NTAPI
143 {
144  /* Standby list or higher, unlinked, and with references */
145  return !MiIsPfnFree(Pfn1);
146 }
147 
148 PMDL
149 NTAPI
154  IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute,
155  IN ULONG MdlFlags)
156 {
157  PMDL Mdl;
158  PFN_NUMBER PageCount, LowPage, HighPage, SkipPages, PagesFound = 0, Page;
159  PPFN_NUMBER MdlPage, LastMdlPage;
160  KIRQL OldIrql;
161  PMMPFN Pfn1;
162  INT LookForZeroedPages;
164  DPRINT1("ARM3-DEBUG: Being called with %I64x %I64x %I64x %lx %d %lu\n", LowAddress, HighAddress, SkipBytes, TotalBytes, CacheAttribute, MdlFlags);
165 
166  //
167  // Convert the low address into a PFN
168  //
169  LowPage = (PFN_NUMBER)(LowAddress.QuadPart >> PAGE_SHIFT);
170 
171  //
172  // Convert, and normalize, the high address into a PFN
173  //
174  HighPage = (PFN_NUMBER)(HighAddress.QuadPart >> PAGE_SHIFT);
175  if (HighPage > MmHighestPhysicalPage) HighPage = MmHighestPhysicalPage;
176 
177  //
178  // Validate skipbytes and convert them into pages
179  //
180  if (BYTE_OFFSET(SkipBytes.LowPart)) return NULL;
181  SkipPages = (PFN_NUMBER)(SkipBytes.QuadPart >> PAGE_SHIFT);
182 
183  /* This isn't supported at all */
184  if (SkipPages) DPRINT1("WARNING: Caller requesting SkipBytes, MDL might be mismatched\n");
185 
186  //
187  // Now compute the number of pages the MDL will cover
188  //
189  PageCount = (PFN_NUMBER)ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, TotalBytes);
190  do
191  {
192  //
193  // Try creating an MDL for these many pages
194  //
195  Mdl = MmCreateMdl(NULL, NULL, PageCount << PAGE_SHIFT);
196  if (Mdl) break;
197 
198  //
199  // This function is not required to return the amount of pages requested
200  // In fact, it can return as little as 1 page, and callers are supposed
201  // to deal with this scenario. So re-attempt the allocation with less
202  // pages than before, and see if it worked this time.
203  //
204  PageCount -= (PageCount >> 4);
205  } while (PageCount);
206 
207  //
208  // Wow, not even a single page was around!
209  //
210  if (!Mdl) return NULL;
211 
212  //
213  // This is where the page array starts....
214  //
215  MdlPage = (PPFN_NUMBER)(Mdl + 1);
216 
217  //
218  // Lock the PFN database
219  //
221 
222  //
223  // Are we looking for any pages, without discriminating?
224  //
225  if ((LowPage == 0) && (HighPage == MmHighestPhysicalPage))
226  {
227  //
228  // Well then, let's go shopping
229  //
230  while (PagesFound < PageCount)
231  {
232  /* Grab a page */
234  MI_SET_PROCESS2("Kernel");
235 
236  /* FIXME: This check should be smarter */
237  Page = 0;
238  if (MmAvailablePages != 0)
239  Page = MiRemoveAnyPage(0);
240 
241  if (Page == 0)
242  {
243  /* This is not good... hopefully we have at least SOME pages */
244  ASSERT(PagesFound);
245  break;
246  }
247 
248  /* Grab the page entry for it */
249  Pfn1 = MiGetPfnEntry(Page);
250 
251  //
252  // Make sure it's really free
253  //
254  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
255 
256  /* Now setup the page and mark it */
257  Pfn1->u3.e2.ReferenceCount = 1;
258  Pfn1->u2.ShareCount = 1;
259  MI_SET_PFN_DELETED(Pfn1);
260  Pfn1->u4.PteFrame = 0x1FFEDCB;
261  Pfn1->u3.e1.StartOfAllocation = 1;
262  Pfn1->u3.e1.EndOfAllocation = 1;
263  Pfn1->u4.VerifierAllocation = 0;
264 
265  //
266  // Save it into the MDL
267  //
268  *MdlPage++ = MiGetPfnEntryIndex(Pfn1);
269  PagesFound++;
270  }
271  }
272  else
273  {
274  //
275  // You want specific range of pages. We'll do this in two runs
276  //
277  for (LookForZeroedPages = 1; LookForZeroedPages >= 0; LookForZeroedPages--)
278  {
279  //
280  // Scan the range you specified
281  //
282  for (Page = LowPage; Page < HighPage; Page++)
283  {
284  //
285  // Get the PFN entry for this page
286  //
287  Pfn1 = MiGetPfnEntry(Page);
288  ASSERT(Pfn1);
289 
290  //
291  // Make sure it's free and if this is our first pass, zeroed
292  //
293  if (MiIsPfnInUse(Pfn1)) continue;
294  if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) != LookForZeroedPages) continue;
295 
296  /* Remove the page from the free or zero list */
297  ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
299  MI_SET_PROCESS2("Kernel");
301 
302  //
303  // Sanity checks
304  //
305  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
306 
307  //
308  // Now setup the page and mark it
309  //
310  Pfn1->u3.e2.ReferenceCount = 1;
311  Pfn1->u2.ShareCount = 1;
312  MI_SET_PFN_DELETED(Pfn1);
313  Pfn1->u4.PteFrame = 0x1FFEDCB;
314  Pfn1->u3.e1.StartOfAllocation = 1;
315  Pfn1->u3.e1.EndOfAllocation = 1;
316  Pfn1->u4.VerifierAllocation = 0;
317 
318  //
319  // Save this page into the MDL
320  //
321  *MdlPage++ = Page;
322  if (++PagesFound == PageCount) break;
323  }
324 
325  //
326  // If the first pass was enough, don't keep going, otherwise, go again
327  //
328  if (PagesFound == PageCount) break;
329  }
330  }
331 
332  //
333  // Now release the PFN count
334  //
336 
337  //
338  // We might've found less pages, but not more ;-)
339  //
340  if (PagesFound != PageCount) ASSERT(PagesFound < PageCount);
341  if (!PagesFound)
342  {
343  //
344  // If we didn' tfind any pages at all, fail
345  //
346  DPRINT1("NO MDL PAGES!\n");
348  return NULL;
349  }
350 
351  //
352  // Write out how many pages we found
353  //
354  Mdl->ByteCount = (ULONG)(PagesFound << PAGE_SHIFT);
355 
356  //
357  // Terminate the MDL array if there's certain missing pages
358  //
359  if (PagesFound != PageCount) *MdlPage = LIST_HEAD;
360 
361  //
362  // Now go back and loop over all the MDL pages
363  //
364  MdlPage = (PPFN_NUMBER)(Mdl + 1);
365  LastMdlPage = MdlPage + PagesFound;
366  while (MdlPage < LastMdlPage)
367  {
368  //
369  // Check if we've reached the end
370  //
371  Page = *MdlPage++;
372  if (Page == LIST_HEAD) break;
373 
374  //
375  // Get the PFN entry for the page and check if we should zero it out
376  //
377  Pfn1 = MiGetPfnEntry(Page);
378  ASSERT(Pfn1);
379  if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPhysicalPage(Page);
381  }
382 
383  //
384  // We're done, mark the pages as locked
385  //
386  Mdl->Process = NULL;
387  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
388  return Mdl;
389 }
390 
391 VOID
392 NTAPI
394 {
395  KIRQL oldIrql;
396  PMMPFN Pfn1;
397 
399  Pfn1 = MiGetPfnEntry(Pfn);
400  ASSERT(Pfn1);
401  ASSERT_IS_ROS_PFN(Pfn1);
402 
403  if (ListHead)
404  {
405  /* Should not be trying to insert an RMAP for a non-active page */
406  ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
407 
408  /* Set the list head address */
409  Pfn1->RmapListHead = ListHead;
410  }
411  else
412  {
413  /* ReactOS semantics dictate the page is STILL active right now */
414  ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
415 
416  /* In this case, the RMAP is actually being removed, so clear field */
417  Pfn1->RmapListHead = NULL;
418 
419  /* ReactOS semantics will now release the page, which will make it free and enter a colored list */
420  }
421 
423 }
424 
426 NTAPI
428 {
429  KIRQL oldIrql;
430  PMM_RMAP_ENTRY ListHead;
431  PMMPFN Pfn1;
432 
433  /* Lock PFN database */
435 
436  /* Get the entry */
437  Pfn1 = MiGetPfnEntry(Pfn);
438  ASSERT(Pfn1);
439  ASSERT_IS_ROS_PFN(Pfn1);
440 
441  /* Get the list head */
442  ListHead = Pfn1->RmapListHead;
443 
444  /* Should not have an RMAP for a non-active page */
445  ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
446 
447  /* Release PFN database and return rmap list head */
449  return ListHead;
450 }
451 
452 VOID
453 NTAPI
455 {
456  KIRQL oldIrql;
457  PMMPFN Pfn1;
458 
459  Pfn1 = MiGetPfnEntry(Pfn);
460  ASSERT(Pfn1);
461  ASSERT_IS_ROS_PFN(Pfn1);
462 
464  Pfn1->u1.SwapEntry = SwapEntry;
466 }
467 
468 SWAPENTRY
469 NTAPI
471 {
472  SWAPENTRY SwapEntry;
473  KIRQL oldIrql;
474  PMMPFN Pfn1;
475 
476  Pfn1 = MiGetPfnEntry(Pfn);
477  ASSERT(Pfn1);
478  ASSERT_IS_ROS_PFN(Pfn1);
479 
481  SwapEntry = Pfn1->u1.SwapEntry;
483 
484  return(SwapEntry);
485 }
486 
487 VOID
488 NTAPI
490 {
491  PMMPFN Pfn1;
492 
493  DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
494 
496  ASSERT(Pfn != 0);
498 
499  Pfn1 = MiGetPfnEntry(Pfn);
500  ASSERT(Pfn1);
501  ASSERT_IS_ROS_PFN(Pfn1);
502 
503  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
504  Pfn1->u3.e2.ReferenceCount++;
505 }
506 
507 ULONG
508 NTAPI
510 {
511  KIRQL oldIrql;
512  ULONG RCount;
513  PMMPFN Pfn1;
514 
515  DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
516 
518  Pfn1 = MiGetPfnEntry(Pfn);
519  ASSERT(Pfn1);
520  ASSERT_IS_ROS_PFN(Pfn1);
521 
522  RCount = Pfn1->u3.e2.ReferenceCount;
523 
525  return(RCount);
526 }
527 
528 BOOLEAN
529 NTAPI
531 {
532  return MiIsPfnInUse(MiGetPfnEntry(Pfn));
533 }
534 
535 VOID
536 NTAPI
538 {
539  PMMPFN Pfn1;
540  KIRQL OldIrql;
541  DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
542 
544 
545  Pfn1 = MiGetPfnEntry(Pfn);
546  ASSERT(Pfn1);
547  ASSERT_IS_ROS_PFN(Pfn1);
548 
549  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
550  Pfn1->u3.e2.ReferenceCount--;
551  if (Pfn1->u3.e2.ReferenceCount == 0)
552  {
553  /* Mark the page temporarily as valid, we're going to make it free soon */
555 
556  /* It's not a ROS PFN anymore */
557  Pfn1->u4.AweAllocation = FALSE;
558 
559  /* Bring it back into the free list */
560  DPRINT("Legacy free: %lx\n", Pfn);
562  }
563 
565 }
566 
568 NTAPI
570 {
571  PFN_NUMBER PfnOffset;
572  PMMPFN Pfn1;
573  KIRQL OldIrql;
574 
576 
577  PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
578  if (!PfnOffset)
579  {
580  KeBugCheck(NO_PAGES_AVAILABLE);
581  }
582 
583  DPRINT("Legacy allocate: %lx\n", PfnOffset);
584  Pfn1 = MiGetPfnEntry(PfnOffset);
585  Pfn1->u3.e2.ReferenceCount = 1;
587 
588  /* This marks the PFN as a ReactOS PFN */
589  Pfn1->u4.AweAllocation = TRUE;
590 
591  /* Allocate the extra ReactOS Data and zero it out */
592  Pfn1->u1.SwapEntry = 0;
593  Pfn1->RmapListHead = NULL;
594 
596  return PfnOffset;
597 }
598 
599 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI MmReferencePage(PFN_NUMBER Pfn)
Definition: freelist.c:489
struct _MMPFN::@1488::@1494 e2
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
VOID NTAPI MmInsertLRULastUserPage(PFN_NUMBER Pfn)
Definition: freelist.c:82
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
Type
Definition: Type.h:6
SIZE_T MmPeakCommitment
Definition: freelist.c:35
SIZE_T MmProcessCommit
Definition: freelist.c:33
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Pfn, SWAPENTRY SwapEntry)
Definition: freelist.c:454
union _MMPFN::@1491 u4
PMMPFN MmPfnDatabase
Definition: freelist.c:24
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
USHORT ReadInProgress
Definition: mm.h:293
ULONG_PTR AweAllocation
Definition: mm.h:353
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:343
PMM_RMAP_ENTRY NTAPI MmGetRmapListHeadPage(PFN_NUMBER Pfn)
Definition: freelist.c:427
BOOLEAN NTAPI MiIsPfnFree(IN PMMPFN Pfn1)
Definition: freelist.c:131
#define TRUE
Definition: numbers.c:17
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:209
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3154
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
union _MMPFN::@1487 u2
PVOID PMDL
Definition: usb.h:39
int32_t INT
Definition: typedefs.h:57
NTSYSAPI ULONG NTAPI RtlFindSetBits(_In_ PRTL_BITMAP BitMapHeader, _In_ ULONG NumberToFind, _In_ ULONG HintIndex)
Definition: bitmap.c:577
USHORT PageLocation
Definition: mm.h:297
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
NTSYSAPI VOID NTAPI RtlInitializeBitMap(_Out_ PRTL_BITMAP BitMapHeader, _In_opt_ __drv_aliasesMem PULONG BitMapBuffer, _In_opt_ ULONG SizeOfBitMap)
UCHAR KIRQL
Definition: env_spec_w32.h:591
SIZE_T MmPagedPoolCommit
Definition: freelist.c:34
MMPFNENTRY e1
Definition: mm.h:329
SIZE_T MmTotalCommittedPages
Definition: freelist.c:30
ULONG * PPFN_NUMBER
Definition: ke.h:8
ULONG PFN_NUMBER
Definition: ke.h:8
#define TAG_MM
Definition: tag.h:136
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
ULONG_PTR ShareCount
Definition: mm.h:322
PFN_NUMBER NTAPI MmGetLRUNextUserPage(PFN_NUMBER PreviousPfn)
Definition: freelist.c:97
#define NULL
Definition: mystdio.h:57
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
NTSYSAPI VOID NTAPI RtlClearAllBits(_In_ PRTL_BITMAP BitMapHeader)
Definition: bitmap.c:272
ULONG_PTR VerifierAllocation
Definition: mm.h:352
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
#define MI_SET_USAGE(x)
Definition: mm.h:253
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
PFN_NUMBER NTAPI MmGetLRUFirstUserPage(VOID)
Definition: freelist.c:63
PFN_NUMBER MmResidentAvailablePages
Definition: freelist.c:27
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
SIZE_T MmDriverCommit
Definition: freelist.c:32
union _MMPFN::@1488 u3
unsigned char BOOLEAN
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define TAG_MDL
Definition: tag.h:86
PMDL NTAPI MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute, IN ULONG MdlFlags)
Definition: freelist.c:150
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PFN_NUMBER NTAPI MmAllocPage(ULONG Type)
Definition: freelist.c:569
PFN_NUMBER MmResidentAvailableAtInit
Definition: freelist.c:28
VOID NTAPI MmDereferencePage(PFN_NUMBER Pfn)
Definition: freelist.c:537
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Pfn)
Definition: freelist.c:470
Definition: mm.h:305
union _MMPFN::@1486 u1
LIST_HEAD(acpi_bus_event_list)
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
UINT64 Position
Definition: acefiex.h:384
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:877
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
ULONG_PTR SIZE_T
Definition: typedefs.h:79
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:161
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
ULONG_PTR PteFrame
Definition: mm.h:350
VOID NTAPI MiInitializeUserPfnBitmap(VOID)
Definition: freelist.c:44
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:31
ULONG_PTR SWAPENTRY
Definition: mm.h:45
SWAPENTRY SwapEntry
Definition: mm.h:316
#define DPRINT1
Definition: precomp.h:8
SIZE_T MmSharedCommit
Definition: freelist.c:31
VOID NTAPI MmSetRmapListHeadPage(PFN_NUMBER Pfn, PMM_RMAP_ENTRY ListHead)
Definition: freelist.c:393
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:897
#define FALSE
Definition: numbers.c:16
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Pfn)
Definition: freelist.c:530
unsigned int ULONG
Definition: retypes.h:1
Definition: mm.h:236
static RTL_BITMAP MiUserPfnBitMap
Definition: freelist.c:38
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Pfn)
Definition: freelist.c:509
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
VOID NTAPI MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
Definition: pfnlist.c:137
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define BYTE_OFFSET(Va)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:226
SIZE_T MmtotalCommitLimitMaximum
Definition: freelist.c:36
VOID NTAPI MmRemoveLRUUserPage(PFN_NUMBER Page)
Definition: freelist.c:116