Author: sir_richard
Date: Sat Feb 25 18:51:21 2012
New Revision: 55858

URL: http://svn.reactos.org/svn/reactos?rev=55858&view=rev
Log:
[NTOS]: Compute the size of, and allocate, the Pool Tracker Table and the Big 
Page Tracker Table, which are the core data structures that make pool tagging 
functionality work.

Modified:
    trunk/reactos/ntoskrnl/mm/ARM3/expool.c
    trunk/reactos/ntoskrnl/mm/ARM3/miarm.h

Modified: trunk/reactos/ntoskrnl/mm/ARM3/expool.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/expool.c?rev=55858&r1=55857&r2=55858&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] Sat Feb 25 18:51:21 
2012
@@ -24,8 +24,11 @@
 POOL_DESCRIPTOR NonPagedPoolDescriptor;
 PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
 PPOOL_DESCRIPTOR PoolVector[2];
-PVOID PoolTrackTable;
 PKGUARDED_MUTEX ExpPagedPoolMutex;
+SIZE_T PoolTrackTableSize, PoolTrackTableMask;
+SIZE_T PoolBigPageTableSize, PoolBigPageTableHash;
+PPOOL_TRACKER_TABLE PoolTrackTable, PoolBigPageTable;
+KSPIN_LOCK ExpTaggedPoolLock;
 
 /* Pool block/header/list access macros */
 #define POOL_ENTRY(x)       (PPOOL_HEADER)((ULONG_PTR)(x) - 
sizeof(POOL_HEADER))
@@ -329,6 +332,11 @@
         ExpInitializePoolListHead(NextEntry);
         NextEntry++;
     }
+
+    //
+    // Note that ReactOS does not support Session Pool Yet
+    //
+    ASSERT(PoolType != PagedPoolSession);
 }
 
 VOID
@@ -338,12 +346,178 @@
                IN ULONG Threshold)
 {
     PPOOL_DESCRIPTOR Descriptor;
+    SIZE_T TableSize;
+    ULONG i;
 
     //
     // Check what kind of pool this is
     //
     if (PoolType == NonPagedPool)
     {
+        //
+        // Compute the track table size and convert it from a power of two to 
an
+        // actual byte size
+        //
+        // NOTE: On checked builds, we'll assert if the registry table size was
+        // invalid, while on retail builds we'll just break out of the loop at
+        // that point.
+        //
+        TableSize = min(PoolTrackTableSize, MmSizeOfNonPagedPoolInBytes >> 8);
+        for (i = 0; i < 32; i++)
+        {
+            if (TableSize & 1)
+            {
+                ASSERT((TableSize & ~1) == 0);
+                if (!(TableSize & ~1)) break;
+            }
+            TableSize >>= 1;
+        }
+
+        //
+        // If we hit bit 32, than no size was defined in the registry, so
+        // we'll use the default size of 2048 entries.
+        //
+        // Otherwise, use the size from the registry, as long as it's not
+        // smaller than 64 entries.
+        //
+        if (i == 32)
+        {
+            PoolTrackTableSize = 2048;
+        }
+        else
+        {
+            PoolTrackTableSize = max(1 << i, 64);
+        }
+
+        //
+        // Loop trying with the biggest specified size first, and cut it down
+        // by a power of two each iteration in case not enough memory exist
+        //
+        while (TRUE)
+        {
+            //
+            // Do not allow overflow
+            //
+            if ((PoolTrackTableSize + 1) > (MAXULONG_PTR / 
sizeof(POOL_TRACKER_TABLE)))
+            {
+                PoolTrackTableSize >>= 1;
+                continue;
+            }
+
+            //
+            // Allocate the tracker table and exit the loop if this worked
+            //
+            PoolTrackTable = MiAllocatePoolPages(NonPagedPool,
+                                                 (PoolTrackTableSize + 1) *
+                                                 sizeof(POOL_TRACKER_TABLE));
+            if (PoolTrackTable) break;
+
+            //
+            // Otherwise, as long as we're not down to the last bit, keep
+            // iterating
+            //
+            if (PoolTrackTableSize == 1)
+            {
+                KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
+                             TableSize,
+                             0xFFFFFFFF,
+                             0xFFFFFFFF,
+                             0xFFFFFFFF);
+            }
+            PoolTrackTableSize >>= 1;
+        }
+
+        //
+        // Finally, add one entry, compute the hash, and zero the table
+        //
+        PoolTrackTableSize++;
+        PoolTrackTableMask = PoolTrackTableSize - 2;
+
+        RtlZeroMemory(PoolTrackTable,
+                      PoolTrackTableSize * sizeof(POOL_TRACKER_TABLE));
+
+        //
+        // We now do the exact same thing with the tracker table for big pages
+        //
+        TableSize = min(PoolBigPageTableSize, MmSizeOfNonPagedPoolInBytes >> 
8);
+        for (i = 0; i < 32; i++)
+        {
+            if (TableSize & 1)
+            {
+                ASSERT((TableSize & ~1) == 0);
+                if (!(TableSize & ~1)) break;
+            }
+            TableSize >>= 1;
+        }
+
+        //
+        // For big pages, the default tracker table is 4096 entries, while the
+        // minimum is still 64
+        //
+        if (i == 32)
+        {
+            PoolBigPageTableSize = 4096;
+        }
+        else
+        {
+            PoolBigPageTableSize = max(1 << i, 64);
+        }
+
+        //
+        // Again, run the exact same loop we ran earlier, but this time for the
+        // big pool tracker instead
+        //
+        while (TRUE)
+        {
+            if ((PoolBigPageTableSize + 1) > (MAXULONG_PTR / 
sizeof(POOL_TRACKER_BIG_PAGES)))
+            {
+                PoolBigPageTableSize >>= 1;
+                continue;
+            }
+
+            PoolBigPageTable = MiAllocatePoolPages(NonPagedPool,
+                                                   PoolBigPageTableSize *
+                                                   
sizeof(POOL_TRACKER_BIG_PAGES));
+            if (PoolBigPageTable) break;
+
+            if (PoolBigPageTableSize == 1)
+            {
+                KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
+                             TableSize,
+                             0xFFFFFFFF,
+                             0xFFFFFFFF,
+                             0xFFFFFFFF);
+            }
+
+            PoolBigPageTableSize >>= 1;
+        }
+
+        //
+        // An extra entry is not needed for for the big pool tracker, so just
+        // compute the hash and zero it
+        //
+        PoolBigPageTableHash = PoolBigPageTableSize - 1;
+        RtlZeroMemory(PoolBigPageTable,
+                      PoolBigPageTableSize * sizeof(POOL_TRACKER_BIG_PAGES));
+
+        //
+        // During development, print this out so we can see what's happening
+        //
+        DPRINT1("EXPOOL: Pool Tracker Table at: 0x%p with 0x%lx bytes\n",
+                PoolTrackTable, PoolTrackTableSize * 
sizeof(POOL_TRACKER_TABLE));
+        DPRINT1("EXPOOL: Big Pool Tracker Table at: 0x%p with 0x%lx bytes\n",
+                PoolBigPageTable, PoolBigPageTableSize * 
sizeof(POOL_TRACKER_BIG_PAGES));
+
+        //
+        // No support for NUMA systems at this time
+        //
+        ASSERT(KeNumberNodes == 1);
+
+        //
+        // Initialize the tag spinlock
+        //
+        KeInitializeSpinLock(&ExpTaggedPoolLock);
+
         //
         // Initialize the nonpaged pool descriptor
         //
@@ -356,6 +530,11 @@
     }
     else
     {
+        //
+        // No support for NUMA systems at this time
+        //
+        ASSERT(KeNumberNodes == 1);
+
         //
         // Allocate the pool descriptor
         //

Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?rev=55858&r1=55857&r2=55858&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sat Feb 25 18:51:21 2012
@@ -345,10 +345,29 @@
 C_ASSERT(sizeof(POOL_HEADER) == POOL_BLOCK_SIZE);
 C_ASSERT(POOL_BLOCK_SIZE == sizeof(LIST_ENTRY));
 
+typedef struct _POOL_TRACKER_TABLE
+{
+    ULONG Key;
+    ULONG NonPagedAllocs;
+    ULONG NonPagedFrees;
+    SIZE_T NonPagedBytes;
+    ULONG PagedAllocs;
+    ULONG PagedFrees;
+    SIZE_T PagedBytes;
+} POOL_TRACKER_TABLE, *PPOOL_TRACKER_TABLE;
+
+typedef struct _POOL_TRACKER_BIG_PAGES
+{
+    PVOID Va;
+    ULONG Key;
+    ULONG NumberOfPages;
+    PVOID QuotaObject;
+} POOL_TRACKER_BIG_PAGES, *PPOOL_TRACKER_BIG_PAGES;
+
 extern ULONG ExpNumberOfPagedPools;
 extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
 extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
-extern PVOID PoolTrackTable;
+extern PPOOL_TRACKER_TABLE PoolTrackTable;
 
 //
 // END FIXFIX


Reply via email to