Author: ros-arm-bringup Date: Mon Jul 27 02:14:56 2009 New Revision: 42249
URL: http://svn.reactos.org/svn/reactos?rev=42249&view=rev Log: - Delete the blaoted, overweight and slow nonpaged pool implementation. - Plug-in support to use the ARM nonpaged pool instead. - This patch has been tested for over 2 months and all known regressions were fixed. - Thanks to Aleksey Bragin for providing a pool regression suite. - Thanks to Aleksey Bragin for providing initial implementation details and code from older attempts. - Thanks to http://uninformed.org/?v=4&a=2&t=txt and http://www.dfrws.org/2008/proceedings/p58-schuster_pres.pdf for allocation strategies.
Removed: trunk/reactos/ntoskrnl/mm/npool.c Modified: trunk/reactos/ntoskrnl/mm/mminit.c trunk/reactos/ntoskrnl/mm/pool.c trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Modified: trunk/reactos/ntoskrnl/mm/mminit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=42... ============================================================================== --- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Mon Jul 27 02:14:56 2009 @@ -45,8 +45,6 @@ "LoaderXIPRom " };
-PVOID MiNonPagedPoolStart; -ULONG MiNonPagedPoolLength; PBOOLEAN Mm64BitPhysicalAddress = FALSE; ULONG MmReadClusterSize; MM_STATS MmStats; @@ -160,18 +158,10 @@ // Initialize ARM³ in phase 1 // MmArmInitSystem(1, KeLoaderBlock); - // DEPRECATED - /* Put nonpaged pool after the loaded modules */ // DEPRECATED - MiNonPagedPoolStart = (PVOID)((ULONG_PTR)MmSystemRangeStart + // DEPRECATED - MmBootImageSize); // DEPRECATED - MiNonPagedPoolLength = MM_NONPAGED_POOL_SIZE; // DEPRECATED - // DEPRECATED - /* Initialize nonpaged pool */ // DEPRECATED - MiInitializeNonPagedPool(); // DEPRECATED - // DEPRECATED - /* Put the paged pool after nonpaged pool */ - MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MiNonPagedPoolStart + - MiNonPagedPoolLength); + + /* Put the paged pool after the loaded modules */ + MmPagedPoolBase = (PVOID)PAGE_ROUND_UP((ULONG_PTR)MmSystemRangeStart + + MmBootImageSize); MmPagedPoolSize = MM_PAGED_POOL_SIZE;
//
Removed: trunk/reactos/ntoskrnl/mm/npool.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/npool.c?rev=422... ============================================================================== --- trunk/reactos/ntoskrnl/mm/npool.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/npool.c (removed) @@ -1,1818 +1,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/npool.c - * PURPOSE: Implements the kernel memory pool - * - * PROGRAMMERS: David Welch (welch@cwcom.net) - * Iwan Fatahi (i_fatahi@hotmail.com) - * Robert Bergkvist (fragdance@hotmail.com) - */ - -/* INCLUDES ****************************************************************/ - -#include <ntoskrnl.h> -#define NDEBUG -#include <debug.h> - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, MiInitializeNonPagedPool) -#endif - -#ifdef ENABLE_VALIDATE_POOL -#define VALIDATE_POOL validate_kernel_pool() -#else -#define VALIDATE_POOL -#endif - -#if 0 -#define POOL_TRACE(args...) do { DbgPrint(args); } while(0); -#else -#if defined(__GNUC__) -#define POOL_TRACE(args...) -#else -#define POOL_TRACE -#endif /* __GNUC__ */ -#endif - -VOID MmPrintMemoryStatistic(VOID); - -#define NPOOL_REDZONE_CHECK /* check the block at deallocation */ -// #define NPOOL_REDZONE_CHECK_FULL /* check all blocks at each allocation/deallocation */ -#define NPOOL_REDZONE_SIZE 8 /* number of red zone bytes */ -#define NPOOL_REDZONE_LOVALUE 0x87 -#define NPOOL_REDZONE_HIVALUE 0xA5 - - -/* avl types ****************************************************************/ - -/* FIXME: - * This declarations should be moved into a separate header file. - */ - -typedef struct _NODE -{ - struct _NODE* link[2]; - struct _NODE* parent; - signed char balance; -} -NODE, *PNODE; - -/* TYPES *******************************************************************/ - -#define BLOCK_HDR_USED_MAGIC (0xdeadbeef) -#define BLOCK_HDR_FREE_MAGIC (0xceadbeef) - -/* - * fields present at the start of a block (this is for internal use only) - */ -typedef struct _HDR -{ - ULONG Magic; - ULONG Size; - struct _HDR* previous; -} HDR, *PHDR; - -typedef struct _HDR_USED -{ - HDR hdr; - LIST_ENTRY ListEntry; - ULONG Tag; - PVOID Caller; - LIST_ENTRY TagListEntry; -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - ULONG UserSize; -#endif - BOOLEAN Dumped; -} HDR_USED, *PHDR_USED; - -typedef struct _HDR_FREE -{ - HDR hdr; - NODE Node; -} HDR_FREE, *PHDR_FREE; - -#define HDR_FREE_SIZE ROUND_UP(sizeof(HDR_FREE), MM_POOL_ALIGNMENT) - -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) -#define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED) + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT) -#else -#define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED), MM_POOL_ALIGNMENT) -#endif - -/* GLOBALS *****************************************************************/ - -extern PVOID MiNonPagedPoolStart; -extern ULONG MiNonPagedPoolLength; - -/* - * Head of the list of free blocks - */ -static PNODE FreeBlockListRoot = NULL; - -/* - * Head of the list of in use block - */ -static LIST_ENTRY UsedBlockListHead; - -static LIST_ENTRY AddressListHead; - -/* - * Count of free blocks - */ -static ULONG EiNrFreeBlocks = 0; - -/* - * Count of used blocks - */ -static ULONG EiNrUsedBlocks = 0; - -/* - * Lock that protects the non-paged pool data structures - */ -static KSPIN_LOCK MmNpoolLock; - -/* - * Total memory used for free nonpaged pool blocks - */ -ULONG EiFreeNonPagedPool = 0; - -/* - * Total memory used for nonpaged pool blocks - */ -ULONG EiUsedNonPagedPool = 0; - -/* Total quota for Non Paged Pool */ -ULONG MmTotalNonPagedPoolQuota = 0; - -#ifdef TAG_STATISTICS_TRACKING -#define TAG_HASH_TABLE_SIZE (1024) -static LIST_ENTRY tag_hash_table[TAG_HASH_TABLE_SIZE]; -#endif /* TAG_STATISTICS_TRACKING */ - -static PULONG MiNonPagedPoolAllocMap; -static ULONG MiNonPagedPoolNrOfPages; - -/* avl helper functions ****************************************************/ - -void DumpFreeBlockNode(PNODE p) -{ - static int count = 0; - HDR_FREE* blk; - - count++; - - if (p) - { - DumpFreeBlockNode(p->link[0]); - blk = CONTAINING_RECORD(p, HDR_FREE, Node); - DbgPrint("%08x %8d (%d)\n", blk, blk->hdr.Size, count); - DumpFreeBlockNode(p->link[1]); - } - - count--; -} -void DumpFreeBlockTree(void) -{ - DbgPrint("--- Begin tree ------------------\n"); - DbgPrint("%08x\n", CONTAINING_RECORD(FreeBlockListRoot, HDR_FREE, Node)); - DumpFreeBlockNode(FreeBlockListRoot); - DbgPrint("--- End tree --------------------\n"); -} - -int compare_node(PNODE p1, PNODE p2) -{ - HDR_FREE* blk1 = CONTAINING_RECORD(p1, HDR_FREE, Node); - HDR_FREE* blk2 = CONTAINING_RECORD(p2, HDR_FREE, Node); - - if (blk1->hdr.Size == blk2->hdr.Size) - { - if (blk1 < blk2) - { - return -1; - } - if (blk1 > blk2) - { - return 1; - } - } - else - { - if (blk1->hdr.Size < blk2->hdr.Size) - { - return -1; - } - if (blk1->hdr.Size > blk2->hdr.Size) - { - return 1; - } - } - return 0; - -} - -int compare_value(PVOID value, PNODE p) -{ - HDR_FREE* blk = CONTAINING_RECORD(p, HDR_FREE, Node); - ULONG v = *(PULONG)value; - - if (v < blk->hdr.Size) - { - return -1; - } - if (v > blk->hdr.Size) - { - return 1; - } - return 0; -} - -/* avl functions **********************************************************/ - -/* FIXME: - * The avl functions should be moved into a separate file. - */ - -/* The avl_insert and avl_remove are based on libavl (library for manipulation of binary trees). */ - -void avl_insert (PNODE * root, PNODE n, int (*compare)(PNODE, PNODE)) -{ - PNODE y; /* Top node to update balance factor, and parent. */ - PNODE p, q; /* Iterator, and parent. */ - PNODE w; /* New root of rebalanced subtree. */ - int dir = 0; /* Direction to descend. */ - - n->link[0] = n->link[1] = n->parent = NULL; - n->balance = 0; - - y = *root; - for (q = NULL, p = *root; p != NULL; q = p, p = p->link[dir]) - { - dir = compare(n, p) > 0; - if (p->balance != 0) - { - y = p; - } - } - - n->parent = q; - if (q != NULL) - { - q->link[dir] = n; - } - else - { - *root = n; - } - - if (*root == n) - { - return; - } - - for (p = n; p != y; p = q) - { - q = p->parent; - dir = q->link[0] != p; - if (dir == 0) - { - q->balance--; - } - else - { - q->balance++; - } - } - - if (y->balance == -2) - { - PNODE x = y->link[0]; - if (x->balance == -1) - { - w = x; - y->link[0] = x->link[1]; - x->link[1] = y; - x->balance = y->balance = 0; - x->parent = y->parent; - y->parent = x; - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - } - else - { - ASSERT(x->balance == +1); - w = x->link[1]; - x->link[1] = w->link[0]; - w->link[0] = x; - y->link[0] = w->link[1]; - w->link[1] = y; - if (w->balance == -1) - { - x->balance = 0; - y->balance = +1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == +1| */ - { - x->balance = -1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[1] != NULL) - { - x->link[1]->parent = x; - } - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - } - } - else if (y->balance == +2) - { - PNODE x = y->link[1]; - if (x->balance == +1) - { - w = x; - y->link[1] = x->link[0]; - x->link[0] = y; - x->balance = y->balance = 0; - x->parent = y->parent; - y->parent = x; - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - } - else - { - ASSERT(x->balance == -1); - w = x->link[0]; - x->link[0] = w->link[1]; - w->link[1] = x; - y->link[1] = w->link[0]; - w->link[0] = y; - if (w->balance == 1) - { - x->balance = 0; - y->balance = -1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == -1| */ - { - x->balance = +1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[0] != NULL) - { - x->link[0]->parent = x; - } - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - } - } - else - { - return; - } - if (w->parent != NULL) - { - w->parent->link[y != w->parent->link[0]] = w; - } - else - { - *root = w; - } - - return; -} - -void avl_remove (PNODE *root, PNODE item, int (*compare)(PNODE, PNODE)) -{ - PNODE p; /* Traverses tree to find node to delete. */ - PNODE q; /* Parent of |p|. */ - int dir; /* Side of |q| on which |p| is linked. */ - - if (root == NULL || *root == NULL) - { - return ; - } - - p = item; - q = p->parent; - if (q == NULL) - { - q = (PNODE) root; - dir = 0; - } - else - { - dir = compare(p, q) > 0; - } - - if (p->link[1] == NULL) - { - q->link[dir] = p->link[0]; - if (q->link[dir] != NULL) - { - q->link[dir]->parent = p->parent; - } - } - else - { - PNODE r = p->link[1]; - if (r->link[0] == NULL) - { - r->link[0] = p->link[0]; - q->link[dir] = r; - r->parent = p->parent; - if (r->link[0] != NULL) - { - r->link[0]->parent = r; - } - r->balance = p->balance; - q = r; - dir = 1; - } - else - { - PNODE s = r->link[0]; - while (s->link[0] != NULL) - { - s = s->link[0]; - } - r = s->parent; - r->link[0] = s->link[1]; - s->link[0] = p->link[0]; - s->link[1] = p->link[1]; - q->link[dir] = s; - if (s->link[0] != NULL) - { - s->link[0]->parent = s; - } - s->link[1]->parent = s; - s->parent = p->parent; - if (r->link[0] != NULL) - { - r->link[0]->parent = r; - } - s->balance = p->balance; - q = r; - dir = 0; - } - } - - item->link[0] = item->link[1] = item->parent = NULL; - item->balance = 0; - - while (q != (PNODE) root) - { - PNODE y = q; - - if (y->parent != NULL) - { - q = y->parent; - } - else - { - q = (PNODE) root; - } - - if (dir == 0) - { - dir = q->link[0] != y; - y->balance++; - if (y->balance == +1) - { - break; - } - else if (y->balance == +2) - { - PNODE x = y->link[1]; - if (x->balance == -1) - { - PNODE w; - - ASSERT(x->balance == -1); - w = x->link[0]; - x->link[0] = w->link[1]; - w->link[1] = x; - y->link[1] = w->link[0]; - w->link[0] = y; - if (w->balance == +1) - { - x->balance = 0; - y->balance = -1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == -1| */ - { - x->balance = +1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[0] != NULL) - { - x->link[0]->parent = x; - } - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - q->link[dir] = w; - } - else - { - y->link[1] = x->link[0]; - x->link[0] = y; - x->parent = y->parent; - y->parent = x; - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - q->link[dir] = x; - if (x->balance == 0) - { - x->balance = -1; - y->balance = +1; - break; - } - else - { - x->balance = y->balance = 0; - y = x; - } - } - } - } - else - { - dir = q->link[0] != y; - y->balance--; - if (y->balance == -1) - { - break; - } - else if (y->balance == -2) - { - PNODE x = y->link[0]; - if (x->balance == +1) - { - PNODE w; - ASSERT(x->balance == +1); - w = x->link[1]; - x->link[1] = w->link[0]; - w->link[0] = x; - y->link[0] = w->link[1]; - w->link[1] = y; - if (w->balance == -1) - { - x->balance = 0; - y->balance = +1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == +1| */ - { - x->balance = -1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[1] != NULL) - { - x->link[1]->parent = x; - } - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - q->link[dir] = w; - } - else - { - y->link[0] = x->link[1]; - x->link[1] = y; - x->parent = y->parent; - y->parent = x; - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - q->link[dir] = x; - if (x->balance == 0) - { - x->balance = +1; - y->balance = -1; - break; - } - else - { - x->balance = y->balance = 0; - y = x; - } - } - } - } - } - -} - -PNODE _cdecl avl_get_first(PNODE root) -{ - PNODE p; - if (root == NULL) - { - return NULL; - } - p = root; - while (p->link[0]) - { - p = p->link[0]; - } - return p; -} - -PNODE avl_get_next(PNODE root, PNODE p) -{ - PNODE q; - if (p->link[1]) - { - p = p->link[1]; - while(p->link[0]) - { - p = p->link[0]; - } - return p; - } - else - { - q = p->parent; - while (q && q->link[1] == p) - { - p = q; - q = q->parent; - } - if (q == NULL) - { - return NULL; - } - else - { - return q; - } - } -} - -PNODE avl_find_equal_or_greater(PNODE root, ULONG size, int (compare)(PVOID, PNODE)) -{ - PNODE p; - PNODE prev = NULL; - int cmp; - - for (p = root; p != NULL;) - { - cmp = compare((PVOID)&size, p); - if (cmp < 0) - { - prev = p; - p = p->link[0]; - } - else if (cmp > 0) - { - p = p->link[1]; - } - else - { - while (p->link[0]) - { - cmp = compare((PVOID)&size, p->link[0]); - if (cmp != 0) - { - break; - } - p = p->link[0]; - } - return p; - } - } - return prev; -} - -/* non paged pool functions ************************************************/ - -#ifdef TAG_STATISTICS_TRACKING -VOID -MiRemoveFromTagHashTable(HDR_USED* block) -/* - * Remove a block from the tag hash table - */ -{ - if (block->Tag == 0) - { - return; - } - RemoveEntryList(&block->TagListEntry); -} - -VOID -MiAddToTagHashTable(HDR_USED* block) -/* - * Add a block to the tag hash table - */ -{ - ULONG hash; - - if (block->Tag == 0) - { - return; - } - - hash = block->Tag % TAG_HASH_TABLE_SIZE; - - InsertHeadList(&tag_hash_table[hash], &block->TagListEntry); -} -#endif /* TAG_STATISTICS_TRACKING */ - -#if defined(TAG_STATISTICS_TRACKING) -VOID static -MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize) -{ - CHAR c1, c2, c3, c4; - - c1 = (CHAR)((CurrentTag >> 24) & 0xFF); - c2 = (CHAR)((CurrentTag >> 16) & 0xFF); - c3 = (CHAR)((CurrentTag >> 8) & 0xFF); - c4 = (CHAR)(CurrentTag & 0xFF); - - if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) - { - DbgPrint("Tag %x (%c%c%c%c) Blocks %d Total Size %d Average Size %d\n", - CurrentTag, c4, c3, c2, c1, CurrentNrBlocks, - CurrentSize, CurrentSize / CurrentNrBlocks); - } - else - { - DbgPrint("Tag %x Blocks %d Total Size %d Average Size %d ", - CurrentTag, CurrentNrBlocks, CurrentSize, - CurrentSize / CurrentNrBlocks); - KeRosPrintAddress((PVOID)CurrentTag); - DbgPrint("\n"); - } -} -#endif /* defined(TAG_STATISTICS_TRACKING) */ - -VOID -NTAPI -MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly) -{ -#if defined(TAG_STATISTICS_TRACKING) - ULONG i; - HDR_USED* current; - ULONG CurrentTag; - ULONG CurrentNrBlocks = 0; - ULONG CurrentSize = 0; - ULONG TotalBlocks; - ULONG TotalSize; - ULONG Size; - LIST_ENTRY tmpListHead; - PLIST_ENTRY current_entry; - - DbgPrint("******* Dumping non paging pool stats ******\n"); - TotalBlocks = 0; - TotalSize = 0; - for (i = 0; i < TAG_HASH_TABLE_SIZE; i++) - { - InitializeListHead(&tmpListHead); - - while (!IsListEmpty(&tag_hash_table[i])) - { - CurrentTag = 0; - - current_entry = tag_hash_table[i].Flink; - while (current_entry != &tag_hash_table[i]) - { - current = CONTAINING_RECORD(current_entry, HDR_USED, TagListEntry); - current_entry = current_entry->Flink; - if (CurrentTag == 0) - { - CurrentTag = current->Tag; - CurrentNrBlocks = 0; - CurrentSize = 0; - } - if (current->Tag == CurrentTag) - { - RemoveEntryList(¤t->TagListEntry); - InsertHeadList(&tmpListHead, ¤t->TagListEntry); - if (!NewOnly || !current->Dumped) - { - CurrentNrBlocks++; - TotalBlocks++; - CurrentSize += current->hdr.Size; - TotalSize += current->hdr.Size; - current->Dumped = TRUE; - } - } - } - if (CurrentTag != 0 && CurrentNrBlocks != 0) - { - MiDumpTagStats(CurrentTag, CurrentNrBlocks, CurrentSize); - } - } - if (!IsListEmpty(&tmpListHead)) - { - tag_hash_table[i].Flink = tmpListHead.Flink; - tag_hash_table[i].Flink->Blink = &tag_hash_table[i]; - tag_hash_table[i].Blink = tmpListHead.Blink; - tag_hash_table[i].Blink->Flink = &tag_hash_table[i]; - } - } - if (TotalBlocks != 0) - { - DbgPrint("TotalBlocks %d TotalSize %d AverageSize %d\n", - TotalBlocks, TotalSize, TotalSize / TotalBlocks); - } - else - { - DbgPrint("TotalBlocks %d TotalSize %d\n", - TotalBlocks, TotalSize); - } - Size = EiFreeNonPagedPool - (MiNonPagedPoolLength - MiNonPagedPoolNrOfPages * PAGE_SIZE); - DbgPrint("Freeblocks %d TotalFreeSize %d AverageFreeSize %d\n", - EiNrFreeBlocks, Size, EiNrFreeBlocks ? Size / EiNrFreeBlocks : 0); - DbgPrint("***************** Dump Complete ***************\n"); -#endif /* defined(TAG_STATISTICS_TRACKING) */ -} - -VOID -NTAPI -MiDebugDumpNonPagedPool(BOOLEAN NewOnly) -{ -#if defined(POOL_DEBUG_APIS) - HDR_USED* current; - PLIST_ENTRY current_entry; - KIRQL oldIrql; - - KeAcquireSpinLock(&MmNpoolLock, &oldIrql); - - DbgPrint("******* Dumping non paging pool contents ******\n"); - current_entry = UsedBlockListHead.Flink; - while (current_entry != &UsedBlockListHead) - { - current = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry); - if (!NewOnly || !current->Dumped) - { - CHAR c1, c2, c3, c4; - - c1 = (CHAR)((current->Tag >> 24) & 0xFF); - c2 = (CHAR)((current->Tag >> 16) & 0xFF); - c3 = (CHAR)((current->Tag >> 8) & 0xFF); - c4 = (CHAR)(current->Tag & 0xFF); - - if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) - { - DbgPrint("Size 0x%x Tag 0x%x (%c%c%c%c) Allocator 0x%x\n", - current->hdr.Size, current->Tag, c4, c3, c2, c1, - current->Caller); - } - else - { - DbgPrint("Size 0x%x Tag 0x%x Allocator 0x%x\n", - current->hdr.Size, current->Tag, current->Caller); - } - current->Dumped = TRUE; - } - current_entry = current_entry->Flink; - } - DbgPrint("***************** Dump Complete ***************\n"); - KeReleaseSpinLock(&MmNpoolLock, oldIrql); -#endif -} - -#ifdef ENABLE_VALIDATE_POOL -static void validate_free_list(void) -/* - * FUNCTION: Validate the integrity of the list of free blocks - */ -{ - HDR_FREE* current; - unsigned int blocks_seen=0; - PNODE p; - - p = avl_get_first(FreeBlockListRoot); - - while(p) - { - PVOID base_addr; - - current = CONTAINING_RECORD(p, HDR_FREE, Node); - base_addr = (PVOID)current; - - if (current->hdr.Magic != BLOCK_HDR_FREE_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KeBugCheck(MEMORY_MANAGEMENT); - } - - if (base_addr < MiNonPagedPoolStart || - (ULONG_PTR)base_addr + current->hdr.Size > (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength) - { - DbgPrint("Block %x found outside pool area\n",current); - DbgPrint("Size %d\n",current->hdr.Size); - DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart, - (ULONG_PTR)MiNonPagedPoolStart+MiNonPagedPoolLength); - KeBugCheck(MEMORY_MANAGEMENT); - } - blocks_seen++; - if (blocks_seen > EiNrFreeBlocks) - { - DbgPrint("Too many blocks on free list\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - p = avl_get_next(FreeBlockListRoot, p); - } -} - -static void validate_used_list(void) -/* - * FUNCTION: Validate the integrity of the list of used blocks - */ -{ - HDR_USED* current; - PLIST_ENTRY current_entry; - unsigned int blocks_seen=0; - - current_entry = UsedBlockListHead.Flink; - while (current_entry != &UsedBlockListHead) - { - PVOID base_addr; - - current = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry); - base_addr = (PVOID)current; - - if (current->hdr.Magic != BLOCK_HDR_USED_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (base_addr < MiNonPagedPoolStart || - ((ULONG_PTR)base_addr+current->hdr.Size) > - (ULONG_PTR)MiNonPagedPoolStart+MiNonPagedPoolLength) - { - DbgPrint("Block %x found outside pool area\n",current); - DbgPrint("Size %d\n",current->hdr.Size); - DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart, - (ULONG_PTR)MiNonPagedPoolStart+MiNonPagedPoolLength); - KeBugCheck(MEMORY_MANAGEMENT); - } - blocks_seen++; - if (blocks_seen > EiNrUsedBlocks) - { - DbgPrint("Too many blocks on used list\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (current->ListEntry.Flink != &UsedBlockListHead && - current->ListEntry.Flink->Blink != ¤t->ListEntry) - { - DbgPrint("%s:%d:Break in list (current %x next %x " - "current->next->previous %x)\n", - __FILE__,__LINE__,current, current->ListEntry.Flink, - current->ListEntry.Flink->Blink); - KeBugCheck(MEMORY_MANAGEMENT); - } - - current_entry = current_entry->Flink; - } -} - -static void check_duplicates(HDR* blk) -/* - * FUNCTION: Check a block has no duplicates - * ARGUMENTS: - * blk = block to check - * NOTE: Bug checks if duplicates are found - */ -{ - ULONG_PTR base = (ULONG_PTR)blk; - ULONG_PTR last = (ULONG_PTR)blk + blk->Size; - PLIST_ENTRY current_entry; - PNODE p; - HDR_FREE* free; - HDR_USED* used; - - p = avl_get_first(FreeBlockListRoot); - - while (p) - { - free = CONTAINING_RECORD(p, HDR_FREE, Node); - if (free->hdr.Magic != BLOCK_HDR_FREE_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - free); - KeBugCheck(MEMORY_MANAGEMENT); - } - - if ( (ULONG_PTR)free > base && (ULONG_PTR)free < last ) - { - DbgPrint("intersecting blocks on list\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if ( (ULONG_PTR)free < base && - ((ULONG_PTR)free + free->hdr.Size) > base ) - { - DbgPrint("intersecting blocks on list\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - p = avl_get_next(FreeBlockListRoot, p); - } - - current_entry = UsedBlockListHead.Flink; - while (current_entry != &UsedBlockListHead) - { - used = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry); - - if ( (ULONG_PTR)used > base && (ULONG_PTR)used < last ) - { - DbgPrint("intersecting blocks on list\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if ( (ULONG_PTR)used < base && - ((ULONG_PTR)used + used->hdr.Size) > base ) - { - DbgPrint("intersecting blocks on list\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - - current_entry = current_entry->Flink; - } - -} - -static void validate_kernel_pool(void) -/* - * FUNCTION: Checks the integrity of the kernel memory heap - */ -{ - HDR_FREE* free; - HDR_USED* used; - PLIST_ENTRY current_entry; - PNODE p; - - validate_free_list(); - validate_used_list(); - - p = avl_get_first(FreeBlockListRoot); - while (p) - { - free = CONTAINING_RECORD(p, HDR_FREE, Node); - check_duplicates(&free->hdr); - p = avl_get_next(FreeBlockListRoot, p); - } - current_entry = UsedBlockListHead.Flink; - while (current_entry != &UsedBlockListHead) - { - used = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry); - check_duplicates(&used->hdr); - current_entry = current_entry->Flink; - } -} -#endif - -#if 0 -static VOID -free_pages(HDR_FREE* blk) -{ - ULONG start; - ULONG end; - - start = (ULONG_PTR)blk; - end = (ULONG_PTR)blk + blk->hdr.Size; - - /* - * If the block doesn't contain a whole page then there is nothing to do - */ - if (PAGE_ROUND_UP(start) >= PAGE_ROUND_DOWN(end)) - { - return; - } -} -#endif - -static void remove_from_used_list(HDR_USED* current) -{ - RemoveEntryList(¤t->ListEntry); - EiUsedNonPagedPool -= current->hdr.Size; - EiNrUsedBlocks--; -} - -static void remove_from_free_list(HDR_FREE* current) -{ - DPRINT("remove_from_free_list %d\n", current->hdr.Size); - - avl_remove(&FreeBlockListRoot, ¤t->Node, compare_node); - - EiFreeNonPagedPool -= current->hdr.Size; - EiNrFreeBlocks--; - DPRINT("remove_from_free_list done\n"); -#ifdef DUMP_AVL - - DumpFreeBlockTree(); -#endif -} - -static void -add_to_free_list(HDR_FREE* blk) -/* - * FUNCTION: add the block to the free list (internal) - */ -{ - HDR_FREE* current; - BOOLEAN UpdatePrevPtr = FALSE; - - DPRINT("add_to_free_list (%d)\n", blk->hdr.Size); - - EiNrFreeBlocks++; - - current = (HDR_FREE*)blk->hdr.previous; - if (current && current->hdr.Magic == BLOCK_HDR_FREE_MAGIC) - { - remove_from_free_list(current); - current->hdr.Size = current->hdr.Size + blk->hdr.Size; - current->hdr.Magic = BLOCK_HDR_USED_MAGIC; - memset(blk, 0xcc, HDR_USED_SIZE); - blk = current; - UpdatePrevPtr = TRUE; - } - - current = (HDR_FREE*)((ULONG_PTR)blk + blk->hdr.Size); - if ((char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength && - current->hdr.Magic == BLOCK_HDR_FREE_MAGIC) - { - remove_from_free_list(current); - blk->hdr.Size += current->hdr.Size; - memset(current, 0xcc, HDR_FREE_SIZE); - UpdatePrevPtr = TRUE; - current = (HDR_FREE*)((ULONG_PTR)blk + blk->hdr.Size); - } - if (UpdatePrevPtr && - (char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) - { - current->hdr.previous = &blk->hdr; - } - DPRINT("%d\n", blk->hdr.Size); - blk->hdr.Magic = BLOCK_HDR_FREE_MAGIC; - EiFreeNonPagedPool += blk->hdr.Size; - avl_insert(&FreeBlockListRoot, &blk->Node, compare_node); - DPRINT("add_to_free_list done\n"); -#ifdef DUMP_AVL - - DumpFreeBlockTree(); -#endif -} - -static void add_to_used_list(HDR_USED* blk) -/* - * FUNCTION: add the block to the used list (internal) - */ -{ - InsertHeadList(&UsedBlockListHead, &blk->ListEntry); - EiUsedNonPagedPool += blk->hdr.Size; - EiNrUsedBlocks++; -} - - -static BOOLEAN -grow_block(HDR_FREE* blk, PVOID end) -{ - NTSTATUS Status; - PFN_TYPE Page[32]; - ULONG_PTR StartIndex, EndIndex; - ULONG i, j, k; - - StartIndex = (ULONG_PTR)(PAGE_ROUND_UP((ULONG_PTR)blk + HDR_FREE_SIZE - (ULONG_PTR)MiNonPagedPoolStart)) / PAGE_SIZE; - EndIndex = ((ULONG_PTR)PAGE_ROUND_UP(end) - (ULONG_PTR)MiNonPagedPoolStart) / PAGE_SIZE; - - - for (i = StartIndex; i < EndIndex; i++) - { - if (!(MiNonPagedPoolAllocMap[i / 32] & (1 << (i % 32)))) - { - for (j = i + 1; j < EndIndex && j - i < 32; j++) - { - if (MiNonPagedPoolAllocMap[j / 32] & (1 << (j % 32))) - { - break; - } - } - for (k = 0; k < j - i; k++) - { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page[k]); - if (!NT_SUCCESS(Status)) - { - for (i = 0; i < k; i++) - { - MmReleasePageMemoryConsumer(MC_NPPOOL, Page[i]); - } - return FALSE; - } - } - Status = MmCreateVirtualMapping(NULL, - (PVOID)((ULONG_PTR)MiNonPagedPoolStart + i * PAGE_SIZE), - PAGE_READWRITE|PAGE_SYSTEM, - Page, - k); - if (!NT_SUCCESS(Status)) - { - for (i = 0; i < k; i++) - { - MmReleasePageMemoryConsumer(MC_NPPOOL, Page[i]); - } - return FALSE; - } - for (j = i; j < k + i; j++) - { - MiNonPagedPoolAllocMap[j / 32] |= (1 << (j % 32)); - } - MiNonPagedPoolNrOfPages += k; - i += k - 1; - } - } - return TRUE; -} - -static HDR_USED* get_block(unsigned int size, unsigned long alignment) -{ - HDR_FREE *blk, *current, *previous = NULL, *next = NULL, *best = NULL; - ULONG previous_size = 0, current_size, next_size = 0, new_size; - PVOID end; - PVOID addr, aligned_addr, best_aligned_addr=NULL; - PNODE p; - - DPRINT("get_block %d\n", size); - - p = avl_find_equal_or_greater(FreeBlockListRoot, size + HDR_USED_SIZE, compare_value); - while (p) - { - current = CONTAINING_RECORD(p, HDR_FREE, Node); - addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE); - /* calculate first aligned address available within this block */ - aligned_addr = alignment > 0 ? MM_ROUND_UP(addr, alignment) : addr; - if (size < PAGE_SIZE) - { - /* check that the block is in one page */ - if (PAGE_ROUND_DOWN(aligned_addr) != PAGE_ROUND_DOWN((ULONG_PTR)aligned_addr + size - 1)) - { - aligned_addr = (PVOID)PAGE_ROUND_UP(aligned_addr); - } - } - DPRINT("%x %x\n", addr, aligned_addr); - if (aligned_addr != addr) - { - while((ULONG_PTR)aligned_addr - (ULONG_PTR)addr < HDR_FREE_SIZE) - { - if (alignment == 0) - { - aligned_addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE + HDR_FREE_SIZE); - } - else - { - aligned_addr = MM_ROUND_UP((PVOID)((ULONG_PTR)current + HDR_USED_SIZE + HDR_FREE_SIZE), alignment); - } - if (size < PAGE_SIZE) - { - /* check that the block is in one page */ - if (PAGE_ROUND_DOWN(aligned_addr) != PAGE_ROUND_DOWN((ULONG_PTR)aligned_addr + size - 1)) - { - aligned_addr = (PVOID)PAGE_ROUND_UP(aligned_addr); - } - } - } - } - DPRINT("%x %x\n", addr, aligned_addr); - new_size = (ULONG_PTR)aligned_addr - (ULONG_PTR)addr + size; - if (current->hdr.Size >= new_size + HDR_USED_SIZE && - (best == NULL || current->hdr.Size < best->hdr.Size)) - { - best = current; - best_aligned_addr = aligned_addr; - if (new_size <= size + 2 * HDR_FREE_SIZE) - { - break; - } - } - - if (best) - { - if (size < PAGE_SIZE) - { - if (current->hdr.Size >= 2 * PAGE_SIZE + HDR_FREE_SIZE) - { - break; - } - } - else - { - if (current->hdr.Size >= size + alignment + HDR_FREE_SIZE) - { - break; - } - } - } - p = avl_get_next(FreeBlockListRoot, p); - } - /* - * We didn't find anything suitable at all. - */ - if (best == NULL) - { - return NULL; - } - - DPRINT(":: blk %x blk->hdr.Size %d (%d) Size %d\n", best, best->hdr.Size, best->hdr.Size - HDR_USED_SIZE, size); - - current = best; - current_size = current->hdr.Size - HDR_USED_SIZE; - addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE); - if (addr != best_aligned_addr) - { - blk = (HDR_FREE*)((ULONG_PTR)best_aligned_addr - HDR_USED_SIZE); - /* - * if size-aligned, break off the preceding bytes into their own block... - */ - previous = current; - previous_size = (ULONG_PTR)blk - (ULONG_PTR)previous - HDR_FREE_SIZE; - current = blk; - current_size -= ((ULONG_PTR)current - (ULONG_PTR)previous); - } - end = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE + size); - - if (current_size >= size + HDR_FREE_SIZE + MM_POOL_ALIGNMENT) - { - /* create a new free block after our block, if the memory size is >= 4 byte for this block */ - next = (HDR_FREE*)((ULONG_PTR)current + size + HDR_USED_SIZE); - next_size = current_size - size - HDR_FREE_SIZE; - current_size = size; - end = (PVOID)((ULONG_PTR)next + HDR_FREE_SIZE); - } - - if (previous) - { - remove_from_free_list(previous); - if (!grow_block(previous, end)) - { - add_to_free_list(previous); - return NULL; - } - memset(current, 0, HDR_USED_SIZE); - current->hdr.Size = current_size + HDR_USED_SIZE; - current->hdr.Magic = BLOCK_HDR_USED_MAGIC; - current->hdr.previous = &previous->hdr; - previous->hdr.Size = previous_size + HDR_FREE_SIZE; - if (next == NULL) - { - blk = (HDR_FREE*)((ULONG_PTR)current + current->hdr.Size); - if ((ULONG_PTR)blk < (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength) - { - blk->hdr.previous = ¤t->hdr; - } - } - - add_to_free_list(previous); - } - else - { - remove_from_free_list(current); - - if (!grow_block(current, end)) - { - add_to_free_list(current); - return NULL; - } - current->hdr.Magic = BLOCK_HDR_USED_MAGIC; - if (next) - { - current->hdr.Size = current_size + HDR_USED_SIZE; - } - } - - if (next) - { - memset(next, 0, HDR_FREE_SIZE); - next->hdr.Size = next_size + HDR_FREE_SIZE; - next->hdr.Magic = BLOCK_HDR_FREE_MAGIC; - next->hdr.previous = ¤t->hdr; - blk = (HDR_FREE*)((ULONG_PTR)next + next->hdr.Size); - if ((ULONG_PTR)blk < (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength) - { - blk->hdr.previous = &next->hdr; - } - add_to_free_list(next); - } - - add_to_used_list((HDR_USED*)current); - VALIDATE_POOL; - - if (size < PAGE_SIZE) - { - addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE); - if (PAGE_ROUND_DOWN(addr) != PAGE_ROUND_DOWN((PVOID)((ULONG_PTR)addr + size - 1))) - { - DPRINT1("%x %x\n", addr, (ULONG_PTR)addr + size); - } - ASSERT (PAGE_ROUND_DOWN(addr) == PAGE_ROUND_DOWN((PVOID)((ULONG_PTR)addr + size - 1))); - } - if (alignment) - { - addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE); - ASSERT(MM_ROUND_UP(addr, alignment) == addr); - } - return (HDR_USED*)current; -} - -ULONG NTAPI -ExRosQueryNonPagedPoolTag ( PVOID Addr ) -{ - HDR_USED* blk=(HDR_USED*)((ULONG_PTR)Addr - HDR_USED_SIZE); - if (blk->hdr.Magic != BLOCK_HDR_USED_MAGIC) - KeBugCheck(MEMORY_MANAGEMENT); - - return blk->Tag; -} - -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) -void check_redzone_header(HDR_USED* hdr) -{ - PUCHAR LoZone = (PUCHAR)((ULONG_PTR)hdr + HDR_USED_SIZE - NPOOL_REDZONE_SIZE); - PUCHAR HiZone = (PUCHAR)((ULONG_PTR)hdr + HDR_USED_SIZE + hdr->UserSize); - BOOLEAN LoOK = TRUE; - BOOLEAN HiOK = TRUE; - ULONG i; - CHAR c[5]; - - for (i = 0; i < NPOOL_REDZONE_SIZE; i++) - { - if (LoZone[i] != NPOOL_REDZONE_LOVALUE) - { - LoOK = FALSE; - } - if (HiZone[i] != NPOOL_REDZONE_HIVALUE) - { - HiOK = FALSE; - } - } - - if (!HiOK || !LoOK) - { - c[0] = (CHAR)((hdr->Tag >> 24) & 0xFF); - c[1] = (CHAR)((hdr->Tag >> 16) & 0xFF); - c[2] = (CHAR)((hdr->Tag >> 8) & 0xFF); - c[3] = (CHAR)(hdr->Tag & 0xFF); - c[4] = 0; - - if (!isprint(c[0]) || !isprint(c[1]) || !isprint(c[2]) || !isprint(c[3])) - { - c[0] = 0; - } - - if (!LoOK) - { - DbgPrint("NPOOL: Low-side redzone overwritten, Block %x, Size %d, Tag %x(%s), Caller %x\n", - (ULONG_PTR)hdr + HDR_USED_SIZE, hdr->UserSize, hdr->Tag, c, hdr->Caller); - } - if (!HiOK) - { - DbgPrint("NPPOL: High-side redzone overwritten, Block %x, Size %d, Tag %x(%s), Caller %x\n", - (ULONG_PTR)hdr + HDR_USED_SIZE, hdr->UserSize, hdr->Tag, c, hdr->Caller); - } - KeBugCheck(MEMORY_MANAGEMENT); - } -} -#endif - -#ifdef NPOOL_REDZONE_CHECK_FULL -void check_redzone_list(void) -{ - PLIST_ENTRY current_entry; - - current_entry = UsedBlockListHead.Flink; - while (current_entry != &UsedBlockListHead) - { - check_redzone_header(CONTAINING_RECORD(current_entry, HDR_USED, ListEntry)); - current_entry = current_entry->Flink; - } -} -#endif - - -VOID NTAPI ExFreeNonPagedPool (PVOID block) -/* - * FUNCTION: Releases previously allocated memory - * ARGUMENTS: - * block = block to free - */ -{ - HDR_USED* blk=(HDR_USED*)((ULONG_PTR)block - HDR_USED_SIZE); - KIRQL oldIrql; - - if (block == NULL) - { - return; - } - - DPRINT("freeing block %x\n",blk); - - POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,blk->hdr.Size, - blk->Caller); - KeAcquireSpinLock(&MmNpoolLock, &oldIrql); - - VALIDATE_POOL; - if (blk->hdr.Magic != BLOCK_HDR_USED_MAGIC) - { - if (blk->hdr.Magic == BLOCK_HDR_FREE_MAGIC) - { - KeBugCheckEx(BAD_POOL_CALLER, 0x07, 0, (ULONG_PTR)blk, (ULONG_PTR)block); - } - else - { - KeBugCheckEx(BAD_POOL_CALLER, 0x46, (ULONG_PTR)block, 0, 0); - } - return; - } - -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - check_redzone_header(blk); -#endif - -#ifdef NPOOL_REDZONE_CHECK_FULL - check_redzone_list(); -#endif - - memset(block, 0xcc, blk->hdr.Size - HDR_USED_SIZE); - -#ifdef TAG_STATISTICS_TRACKING - MiRemoveFromTagHashTable(blk); -#endif - - remove_from_used_list(blk); - blk->hdr.Magic = BLOCK_HDR_FREE_MAGIC; - add_to_free_list((HDR_FREE*)blk); - VALIDATE_POOL; - KeReleaseSpinLock(&MmNpoolLock, oldIrql); -} - -PVOID NTAPI -ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Caller) -{ -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - ULONG UserSize; -#endif - PVOID block; - HDR_USED* best = NULL; - KIRQL oldIrql; - ULONG alignment; - - POOL_TRACE("ExAllocatePool(NumberOfBytes %d) caller %x ", - Size,Caller); - - KeAcquireSpinLock(&MmNpoolLock, &oldIrql); - -#ifdef NPOOL_REDZONE_CHECK_FULL - check_redzone_list(); -#endif - - VALIDATE_POOL; - -#if 1 - /* after some allocations print the npaged pool stats */ -#ifdef TAG_STATISTICS_TRACKING - - { - static ULONG counter = 0; - if (counter++ % 100000 == 0) - { - MiDebugDumpNonPagedPoolStats(FALSE); - MmPrintMemoryStatistic(); - } - } -#endif -#endif - /* - * accomodate this useful idiom - */ - if (Size == 0) - { - POOL_TRACE("= NULL\n"); - KeReleaseSpinLock(&MmNpoolLock, oldIrql); - return(NULL); - } - /* Make the size dword alligned, this makes the block dword alligned */ -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - UserSize = Size; - Size = ROUND_UP(Size + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT); -#else - Size = ROUND_UP(Size, MM_POOL_ALIGNMENT); -#endif - - if (Size >= PAGE_SIZE) - { - alignment = PAGE_SIZE; - } - else if (Type & CACHE_ALIGNED_POOL_MASK) - { - alignment = MM_CACHE_LINE_SIZE; - } - else - { - alignment = 0; - } - - best = get_block(Size, alignment); - if (best == NULL) - { - KeReleaseSpinLock(&MmNpoolLock, oldIrql); - DPRINT1("Trying to allocate %lu bytes from nonpaged pool - nothing suitable found, returning NULL\n", - Size ); - KeRosDumpStackFrames(NULL, 10); - return NULL; - } - best->Tag = Tag; - best->Caller = Caller; - best->Dumped = FALSE; - best->TagListEntry.Flink = best->TagListEntry.Blink = NULL; -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - best->UserSize = UserSize; - memset((PVOID)((ULONG_PTR)best + HDR_USED_SIZE - NPOOL_REDZONE_SIZE), NPOOL_REDZONE_LOVALUE, NPOOL_REDZONE_SIZE); - memset((PVOID)((ULONG_PTR)best + HDR_USED_SIZE + UserSize), NPOOL_REDZONE_HIVALUE, NPOOL_REDZONE_SIZE); -#endif - -#ifdef TAG_STATISTICS_TRACKING - - MiAddToTagHashTable(best); -#endif - - KeReleaseSpinLock(&MmNpoolLock, oldIrql); - block = (PVOID)((ULONG_PTR)best + HDR_USED_SIZE); - /* RtlZeroMemory(block, Size);*/ - return(block); -} - -ULONG NTAPI -EiGetNonPagedPoolTag(PVOID Block) -{ - return ((HDR_USED*)((ULONG_PTR)Block - HDR_USED_SIZE))->Tag; -} - -VOID -INIT_FUNCTION -NTAPI -MiInitializeNonPagedPool(VOID) -{ - NTSTATUS Status; - PFN_TYPE Page; - ULONG i; - PVOID Address; - HDR_USED* used; - HDR_FREE* free; - PVOID BaseAddress; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - PMEMORY_AREA MArea; - BoundaryAddressMultiple.QuadPart = 0; - - BaseAddress = MiNonPagedPoolStart; - MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM | MEMORY_AREA_STATIC, - &BaseAddress, - MiNonPagedPoolLength, - PAGE_READWRITE, - &MArea, - TRUE, - 0, - BoundaryAddressMultiple); - -#ifdef TAG_STATISTICS_TRACKING - - for (i = 0; i < TAG_HASH_TABLE_SIZE; i++) - { - InitializeListHead(&tag_hash_table[i]); - } -#endif - KeInitializeSpinLock(&MmNpoolLock); - InitializeListHead(&UsedBlockListHead); - InitializeListHead(&AddressListHead); - FreeBlockListRoot = NULL; - - MiNonPagedPoolAllocMap = (PVOID)((ULONG_PTR)MiNonPagedPoolStart + PAGE_SIZE); -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - MiNonPagedPoolNrOfPages = ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8; - MiNonPagedPoolNrOfPages = ROUND_UP(MiNonPagedPoolNrOfPages + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT); - MiNonPagedPoolNrOfPages = PAGE_ROUND_UP(MiNonPagedPoolNrOfPages + HDR_FREE_SIZE) + PAGE_SIZE; -#else - MiNonPagedPoolNrOfPages = PAGE_ROUND_UP(ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8 + HDR_FREE_SIZE) + PAGE_SIZE; -#endif - MiNonPagedPoolNrOfPages /= PAGE_SIZE; - Address = MiNonPagedPoolStart; - - for (i = 0; i < MiNonPagedPoolNrOfPages; i++) - { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to allocate a page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - - Status = MmCreateVirtualMapping(NULL, - Address, - PAGE_READWRITE|PAGE_SYSTEM, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - Address = (PVOID)((ULONG_PTR)Address + PAGE_SIZE); - } - - for (i = 0; i < MiNonPagedPoolNrOfPages; i++) - { - MiNonPagedPoolAllocMap[i / 32] |= (1 << (i % 32)); - } - - /* the first block is free */ - free = (HDR_FREE*)MiNonPagedPoolStart; - free->hdr.Magic = BLOCK_HDR_FREE_MAGIC; - free->hdr.Size = PAGE_SIZE - HDR_USED_SIZE; - free->hdr.previous = NULL; - memset((PVOID)((ULONG_PTR)free + HDR_FREE_SIZE), 0xcc, free->hdr.Size - HDR_FREE_SIZE); - add_to_free_list(free); - - /* the second block contains the non paged pool bitmap */ - used = (HDR_USED*)((ULONG_PTR)free + free->hdr.Size); - used->hdr.Magic = BLOCK_HDR_USED_MAGIC; -#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL) - used->UserSize = ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8; - used->hdr.Size = ROUND_UP(used->UserSize + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT) + HDR_USED_SIZE; - memset((PVOID)((ULONG_PTR)used + HDR_USED_SIZE - NPOOL_REDZONE_SIZE), NPOOL_REDZONE_LOVALUE, NPOOL_REDZONE_SIZE); - memset((PVOID)((ULONG_PTR)used + HDR_USED_SIZE + used->UserSize), NPOOL_REDZONE_HIVALUE, NPOOL_REDZONE_SIZE); -#else - used->hdr.Size = ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8 + HDR_USED_SIZE; -#endif - used->hdr.previous = &free->hdr; - used->Tag = 0xffffffff; - used->Caller = (PVOID)MiInitializeNonPagedPool; - used->Dumped = FALSE; - add_to_used_list(used); -#ifdef TAG_STATISTICS_TRACKING - MiAddToTagHashTable(used); -#endif - - /* the third block is the free block after the bitmap */ - free = (HDR_FREE*)((ULONG_PTR)used + used->hdr.Size); - free->hdr.Magic = BLOCK_HDR_FREE_MAGIC; - free->hdr.Size = MiNonPagedPoolLength - ((ULONG_PTR)free - (ULONG_PTR)MiNonPagedPoolStart); - free->hdr.previous = &used->hdr; - memset((PVOID)((ULONG_PTR)free + HDR_FREE_SIZE), 0xcc, (ULONG_PTR)Address - (ULONG_PTR)free - HDR_FREE_SIZE); - add_to_free_list(free); -} - -PVOID -NTAPI -MiAllocateSpecialPool (IN POOL_TYPE PoolType, - IN SIZE_T NumberOfBytes, - IN ULONG Tag, - IN ULONG Underrun - ) -{ - /* FIXME: Special Pools not Supported */ - DbgPrint("Special Pools not supported\n"); - return NULL; -} - -/* EOF */
Modified: trunk/reactos/ntoskrnl/mm/pool.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/pool.c?rev=4224... ============================================================================== --- trunk/reactos/ntoskrnl/mm/pool.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/pool.c [iso-8859-1] Mon Jul 27 02:14:56 2009 @@ -33,6 +33,12 @@ ULONG NTAPI EiGetNonPagedPoolTag(IN PVOID Block);
+PVOID +NTAPI +ExAllocateArmPoolWithTag(POOL_TYPE PoolType, + SIZE_T NumberOfBytes, + ULONG Tag); + static PVOID NTAPI EiAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes, @@ -75,7 +81,7 @@ Block = ExpAllocateDebugPool(PoolType, NumberOfBytes, Tag, Caller, TRUE); else #endif - Block = ExAllocateNonPagedPoolWithTag(PoolType, NumberOfBytes, Tag, Caller); + Block = ExAllocateArmPoolWithTag(PoolType, NumberOfBytes, Tag); }
if ((PoolType & MUST_SUCCEED_POOL_MASK) && !Block) @@ -183,19 +189,8 @@ IN EX_POOL_PRIORITY Priority ) { - /* Check if this is one of the "Special" Flags, used by the Verifier */ - if (Priority & 8) { - /* Check if this is a xxSpecialUnderrun */ - if (Priority & 1) { - return MiAllocateSpecialPool(PoolType, NumberOfBytes, Tag, 1); - } else { /* xxSpecialOverrun */ - return MiAllocateSpecialPool(PoolType, NumberOfBytes, Tag, 0); - } - } - - /* FIXME: Do Ressource Checking Based on Priority and fail if resources too low*/ - /* Do the allocation */ + UNIMPLEMENTED; return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); }
@@ -253,6 +248,11 @@ ExFreePoolWithTag(Block, 0); }
+VOID +NTAPI +ExFreeArmPoolWithTag(PVOID P, + ULONG TagToFree); + /* * @implemented */ @@ -291,36 +291,7 @@ #endif ExFreePagedPool(Block); } - - /* Check for non-paged pool */ - else if (Block >= MiNonPagedPoolStart && - (char*)Block < ((char*)MiNonPagedPoolStart + MiNonPagedPoolLength)) - { - /* Validate tag */ -#ifndef DEBUG_NPOOL - if (Tag != 0 && Tag != EiGetNonPagedPoolTag(Block)) - KeBugCheckEx(BAD_POOL_CALLER, - 0x0a, - (ULONG_PTR)Block, - EiGetNonPagedPoolTag(Block), - Tag); -#endif - /* Validate IRQL */ - if (KeGetCurrentIrql() > DISPATCH_LEVEL) - KeBugCheckEx(BAD_POOL_CALLER, - 0x09, - KeGetCurrentIrql(), - NonPagedPool, - (ULONG_PTR)Block); - - /* Free from non-paged pool */ -#ifdef DEBUG_NPOOL - if (ExpIsPoolTagDebuggable(Tag)) - ExpFreeDebugPool(Block, FALSE); - else -#endif - ExFreeNonPagedPool(Block); - } + else if (Block) return ExFreeArmPoolWithTag(Block, Tag); else { /* Warn only for NULL pointers */ @@ -403,13 +374,6 @@ /* Check if we still have 200 pages free*/ if (MmStats.NrFreePages < 200) return FALSE;
- /* Check that 4MB is still left */ - if ((MM_NONPAGED_POOL_SIZE >> 12) < ((MiNonPagedPoolLength + 4194304) >> 12)) { - return FALSE; - } - - /* Increase Non Paged Pool Quota by 64K */ - MmTotalNonPagedPoolQuota += 65536; *NewMaxQuota = CurrentMaxQuota + 65536; return TRUE; }
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.r... ============================================================================== --- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Mon Jul 27 02:14:56 2009 @@ -390,7 +390,6 @@ <file>mmsup.c</file> <file>mminit.c</file> <file>mpw.c</file> - <file>npool.c</file> <file>pagefile.c</file> <file>pageop.c</file> <file>pe.c</file>