ReactOS  0.4.15-dev-316-g938df97
freelist.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include "ARM3/miarm.h"
Include dependency graph for freelist.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 
#define ASSERT_IS_ROS_PFN(x)   ASSERT(MI_IS_ROS_PFN(x) == TRUE);
 

Functions

VOID NTAPI MiInitializeUserPfnBitmap (VOID)
 
PFN_NUMBER NTAPI MmGetLRUFirstUserPage (VOID)
 
VOID NTAPI MmInsertLRULastUserPage (PFN_NUMBER Pfn)
 
PFN_NUMBER NTAPI MmGetLRUNextUserPage (PFN_NUMBER PreviousPfn)
 
VOID NTAPI MmRemoveLRUUserPage (PFN_NUMBER Page)
 
BOOLEAN NTAPI MiIsPfnFree (IN PMMPFN Pfn1)
 
BOOLEAN NTAPI MiIsPfnInUse (IN PMMPFN Pfn1)
 
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)
 
VOID NTAPI MmSetRmapListHeadPage (PFN_NUMBER Pfn, PMM_RMAP_ENTRY ListHead)
 
PMM_RMAP_ENTRY NTAPI MmGetRmapListHeadPage (PFN_NUMBER Pfn)
 
VOID NTAPI MmSetSavedSwapEntryPage (PFN_NUMBER Pfn, SWAPENTRY SwapEntry)
 
SWAPENTRY NTAPI MmGetSavedSwapEntryPage (PFN_NUMBER Pfn)
 
VOID NTAPI MmReferencePage (PFN_NUMBER Pfn)
 
ULONG NTAPI MmGetReferenceCountPage (PFN_NUMBER Pfn)
 
BOOLEAN NTAPI MmIsPageInUse (PFN_NUMBER Pfn)
 
VOID NTAPI MmDereferencePage (PFN_NUMBER Pfn)
 
PFN_NUMBER NTAPI MmAllocPage (ULONG Type)
 

Variables

PMMPFN MmPfnDatabase
 
PFN_NUMBER MmAvailablePages
 
PFN_NUMBER MmResidentAvailablePages
 
PFN_NUMBER MmResidentAvailableAtInit
 
SIZE_T MmTotalCommittedPages
 
SIZE_T MmSharedCommit
 
SIZE_T MmDriverCommit
 
SIZE_T MmProcessCommit
 
SIZE_T MmPagedPoolCommit
 
SIZE_T MmPeakCommitment
 
SIZE_T MmtotalCommitLimitMaximum
 
static RTL_BITMAP MiUserPfnBitMap
 

Macro Definition Documentation

◆ ASSERT_IS_ROS_PFN

#define ASSERT_IS_ROS_PFN (   x)    ASSERT(MI_IS_ROS_PFN(x) == TRUE);

Definition at line 20 of file freelist.c.

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 17 of file freelist.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file freelist.c.

Function Documentation

◆ MiAllocatePagesForMdl()

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 at line 150 of file freelist.c.

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  //
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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union _MMPFN::@1773 u3
USHORT ReadInProgress
Definition: mm.h:293
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
union _MMPFN::@1772 u2
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
int32_t INT
Definition: typedefs.h:57
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
USHORT PageLocation
Definition: mm.h:297
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
union _MMPFN::@1776 u4
ULONG * PPFN_NUMBER
Definition: ke.h:8
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:322
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
smooth NULL
Definition: ftsmooth.c:416
ULONG_PTR VerifierAllocation
Definition: mm.h:352
#define MI_SET_USAGE(x)
Definition: mm.h:253
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define TAG_MDL
Definition: tag.h:86
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:305
ULONG LowPart
Definition: typedefs.h:105
LIST_HEAD(acpi_bus_event_list)
struct _MMPFN::@1773::@1779 e2
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:190
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
ULONG_PTR PteFrame
Definition: mm.h:350
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:382
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:960
unsigned int ULONG
Definition: retypes.h:1
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
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
LONGLONG QuadPart
Definition: typedefs.h:113

Referenced by MmAllocateNonCachedMemory(), MmAllocatePagesForMdl(), and MmAllocatePagesForMdlEx().

◆ MiInitializeUserPfnBitmap()

VOID NTAPI MiInitializeUserPfnBitmap ( VOID  )

Definition at line 44 of file freelist.c.

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 */
56  Bitmap,
59 }
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define TAG_MM
Definition: tag.h:136
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
unsigned int ULONG
Definition: retypes.h:1
static RTL_BITMAP MiUserPfnBitMap
Definition: freelist.c:38
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31

Referenced by MmInitSystem().

◆ MiIsPfnFree()

BOOLEAN NTAPI MiIsPfnFree ( IN PMMPFN  Pfn1)

Definition at line 131 of file freelist.c.

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 }

Referenced by MiIsPfnInUse().

◆ MiIsPfnInUse()

BOOLEAN NTAPI MiIsPfnInUse ( IN PMMPFN  Pfn1)

Definition at line 142 of file freelist.c.

143 {
144  /* Standby list or higher, unlinked, and with references */
145  return !MiIsPfnFree(Pfn1);
146 }
BOOLEAN NTAPI MiIsPfnFree(IN PMMPFN Pfn1)
Definition: freelist.c:131

Referenced by MiAllocatePagesForMdl(), MiFindContiguousPages(), MmGetRmapListHeadPage(), MmIsPageInUse(), and MmSetRmapListHeadPage().

◆ MmAllocPage()

PFN_NUMBER NTAPI MmAllocPage ( ULONG  Type)

Definition at line 569 of file freelist.c.

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 }
#define TRUE
Definition: types.h:120
union _MMPFN::@1773 u3
ULONG_PTR AweAllocation
Definition: mm.h:353
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:343
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:238
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
USHORT PageLocation
Definition: mm.h:297
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
union _MMPFN::@1776 u4
ULONG PFN_NUMBER
Definition: ke.h:8
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1428
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:305
struct _MMPFN::@1773::@1779 e2
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
SWAPENTRY SwapEntry
Definition: mm.h:316
union _MMPFN::@1771 u1

Referenced by MmRequestPageMemoryConsumer().

◆ MmDereferencePage()

VOID NTAPI MmDereferencePage ( PFN_NUMBER  Pfn)

Definition at line 537 of file freelist.c.

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 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union _MMPFN::@1773 u3
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
ULONG_PTR AweAllocation
Definition: mm.h:353
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
USHORT PageLocation
Definition: mm.h:297
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
union _MMPFN::@1776 u4
void DPRINT(...)
Definition: polytest.cpp:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:305
struct _MMPFN::@1773::@1779 e2
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940

Referenced by MmReleasePageMemoryConsumer().

◆ MmGetLRUFirstUserPage()

PFN_NUMBER NTAPI MmGetLRUFirstUserPage ( VOID  )

Definition at line 63 of file freelist.c.

64 {
66  KIRQL OldIrql;
67 
68  /* Find the first user page */
72  if (Position == 0xFFFFFFFF) return 0;
73 
74  /* Return it */
75  ASSERT(Position != 0);
77  return Position;
78 }
static COORD Position
Definition: mouse.c:34
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP, ULONG, ULONG)
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
unsigned int ULONG
Definition: retypes.h:1
static RTL_BITMAP MiUserPfnBitMap
Definition: freelist.c:38

Referenced by MmTrimUserMemory().

◆ MmGetLRUNextUserPage()

PFN_NUMBER NTAPI MmGetLRUNextUserPage ( PFN_NUMBER  PreviousPfn)

Definition at line 97 of file freelist.c.

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);
111  return Position;
112 }
static COORD Position
Definition: mouse.c:34
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP, ULONG, ULONG)
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
unsigned int ULONG
Definition: retypes.h:1
static RTL_BITMAP MiUserPfnBitMap
Definition: freelist.c:38

Referenced by MmTrimUserMemory().

◆ MmGetReferenceCountPage()

ULONG NTAPI MmGetReferenceCountPage ( PFN_NUMBER  Pfn)

Definition at line 509 of file freelist.c.

510 {
511  KIRQL oldIrql;
512  ULONG RCount;
513  PMMPFN Pfn1;
514 
515  DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
516 
517  oldIrql = MiAcquirePfnLock();
518  Pfn1 = MiGetPfnEntry(Pfn);
519  ASSERT(Pfn1);
520  ASSERT_IS_ROS_PFN(Pfn1);
521 
522  RCount = Pfn1->u3.e2.ReferenceCount;
523 
524  MiReleasePfnLock(oldIrql);
525  return(RCount);
526 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union _MMPFN::@1773 u3
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
void DPRINT(...)
Definition: polytest.cpp:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
struct _MMPFN::@1773::@1779 e2
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
unsigned int ULONG
Definition: retypes.h:1

Referenced by CcFreeCachePage(), MiFreeSegmentPage(), MmFinalizeSectionPageOut(), MmPageOutSectionView(), MmpPageOutPhysicalAddress(), and MmReleasePageMemoryConsumer().

◆ MmGetRmapListHeadPage()

PMM_RMAP_ENTRY NTAPI MmGetRmapListHeadPage ( PFN_NUMBER  Pfn)

Definition at line 427 of file freelist.c.

428 {
429  KIRQL oldIrql;
430  PMM_RMAP_ENTRY ListHead;
431  PMMPFN Pfn1;
432 
433  /* Lock PFN database */
434  oldIrql = MiAcquirePfnLock();
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 */
448  MiReleasePfnLock(oldIrql);
449  return ListHead;
450 }
#define TRUE
Definition: types.h:120
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:343
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142
Definition: mm.h:236

Referenced by _MmSetPageEntrySectionSegment(), MmDeleteAllRmaps(), MmDeleteRmap(), MmDeleteSectionAssociation(), MmGetSegmentRmap(), MmInsertRmap(), MmIsDirtyPageRmap(), MmPageOutPhysicalAddress(), MmpPageOutPhysicalAddress(), MmSetCleanAllRmaps(), and MmSetDirtyAllRmaps().

◆ MmGetSavedSwapEntryPage()

SWAPENTRY NTAPI MmGetSavedSwapEntryPage ( PFN_NUMBER  Pfn)

Definition at line 470 of file freelist.c.

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 
480  oldIrql = MiAcquirePfnLock();
481  SwapEntry = Pfn1->u1.SwapEntry;
482  MiReleasePfnLock(oldIrql);
483 
484  return(SwapEntry);
485 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
ULONG_PTR SWAPENTRY
Definition: mm.h:47
SWAPENTRY SwapEntry
Definition: mm.h:316
union _MMPFN::@1771 u1

Referenced by MmFinalizeSectionPageOut(), MmFreeSectionPage(), MmPageOutSectionView(), MmpFreePageFileSegment(), MmUnsharePageEntrySectionSegment(), and MmWritePageSectionView().

◆ MmInsertLRULastUserPage()

VOID NTAPI MmInsertLRULastUserPage ( PFN_NUMBER  Pfn)

Definition at line 82 of file freelist.c.

83 {
84  KIRQL OldIrql;
85 
86  /* Set the page as a user page */
87  ASSERT(Pfn != 0);
93 }
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3154
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
unsigned int ULONG
Definition: retypes.h:1
static RTL_BITMAP MiUserPfnBitMap
Definition: freelist.c:38

Referenced by MmRequestPageMemoryConsumer().

◆ MmIsPageInUse()

BOOLEAN NTAPI MmIsPageInUse ( PFN_NUMBER  Pfn)

Definition at line 530 of file freelist.c.

531 {
532  return MiIsPfnInUse(MiGetPfnEntry(Pfn));
533 }
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142

Referenced by MmCreateVirtualMapping().

◆ MmReferencePage()

VOID NTAPI MmReferencePage ( PFN_NUMBER  Pfn)

Definition at line 489 of file freelist.c.

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 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union _MMPFN::@1773 u3
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
void DPRINT(...)
Definition: polytest.cpp:61
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
struct _MMPFN::@1773::@1779 e2
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31

Referenced by _MiFlushMappedSection(), MmNotPresentFaultCachePage(), and MmPageOutSectionView().

◆ MmRemoveLRUUserPage()

VOID NTAPI MmRemoveLRUUserPage ( PFN_NUMBER  Page)

Definition at line 116 of file freelist.c.

117 {
118  KIRQL OldIrql;
119 
120  /* Unset the page as a user page */
121  ASSERT(Page != 0);
127 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3154
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
unsigned int ULONG
Definition: retypes.h:1
static RTL_BITMAP MiUserPfnBitMap
Definition: freelist.c:38

Referenced by MmReleasePageMemoryConsumer().

◆ MmSetRmapListHeadPage()

VOID NTAPI MmSetRmapListHeadPage ( PFN_NUMBER  Pfn,
PMM_RMAP_ENTRY  ListHead 
)

Definition at line 393 of file freelist.c.

394 {
395  KIRQL oldIrql;
396  PMMPFN Pfn1;
397 
398  oldIrql = MiAcquirePfnLock();
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 
422  MiReleasePfnLock(oldIrql);
423 }
#define TRUE
Definition: types.h:120
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:343
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142

◆ MmSetSavedSwapEntryPage()

VOID NTAPI MmSetSavedSwapEntryPage ( PFN_NUMBER  Pfn,
SWAPENTRY  SwapEntry 
)

Definition at line 454 of file freelist.c.

455 {
456  KIRQL oldIrql;
457  PMMPFN Pfn1;
458 
459  Pfn1 = MiGetPfnEntry(Pfn);
460  ASSERT(Pfn1);
461  ASSERT_IS_ROS_PFN(Pfn1);
462 
463  oldIrql = MiAcquirePfnLock();
464  Pfn1->u1.SwapEntry = SwapEntry;
465  MiReleasePfnLock(oldIrql);
466 }
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define ASSERT_IS_ROS_PFN(x)
Definition: freelist.c:20
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: mm.h:305
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
SWAPENTRY SwapEntry
Definition: mm.h:316
union _MMPFN::@1771 u1

Referenced by MiSwapInPage(), MmFinalizeSectionPageOut(), MmFreeCacheSectionPage(), MmFreeSectionPage(), MmNotPresentFaultCachePage(), MmNotPresentFaultSectionView(), MmPageOutSectionView(), MmpFreePageFileSegment(), MmUnsharePageEntrySectionSegment(), and MmWritePageSectionView().

Variable Documentation

◆ MiUserPfnBitMap

◆ MmAvailablePages

◆ MmDriverCommit

SIZE_T MmDriverCommit

Definition at line 32 of file freelist.c.

◆ MmPagedPoolCommit

SIZE_T MmPagedPoolCommit

Definition at line 34 of file freelist.c.

◆ MmPeakCommitment

SIZE_T MmPeakCommitment

Definition at line 35 of file freelist.c.

◆ MmPfnDatabase

◆ MmProcessCommit

SIZE_T MmProcessCommit

Definition at line 33 of file freelist.c.

◆ MmResidentAvailableAtInit

PFN_NUMBER MmResidentAvailableAtInit

Definition at line 28 of file freelist.c.

Referenced by MmArmInitSystem().

◆ MmResidentAvailablePages

PFN_NUMBER MmResidentAvailablePages

Definition at line 27 of file freelist.c.

Referenced by MiInitializeSpecialPool(), MmAdjustWorkingSetSize(), and MmArmInitSystem().

◆ MmSharedCommit

SIZE_T MmSharedCommit

Definition at line 31 of file freelist.c.

Referenced by MmCommitSessionMappedView().

◆ MmtotalCommitLimitMaximum

SIZE_T MmtotalCommitLimitMaximum

Definition at line 36 of file freelist.c.

◆ MmTotalCommittedPages

SIZE_T MmTotalCommittedPages

Definition at line 30 of file freelist.c.