https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3f601122bce70808381d2255abb938f9369f2eb5

commit 3f601122bce70808381d2255abb938f9369f2eb5
Author:     Victor Perevertkin <[email protected]>
AuthorDate: Mon Jun 14 04:50:01 2021 +0300
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Jun 16 12:14:27 2021 +0200

    [NTOS:MM] Fix placing entries into MmNonPagedPoolFreeListHead
    
    When freeing pages, free page entries with pages num == 3 were
    incorrectly treated as entries with pages num >= 4 and thus
    their re-insertion was not triggered. That lead to non paged pool
    fragmentation (can be triggered by kmtest:ExPools, for example)
    
    Also, altered the index acquisition code for MmNonPagedPoolFreeList
    entries so it looks more clear
---
 ntoskrnl/mm/ARM3/pool.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/ntoskrnl/mm/ARM3/pool.c b/ntoskrnl/mm/ARM3/pool.c
index 5a406e166d8..fe8d6cd1a74 100644
--- a/ntoskrnl/mm/ARM3/pool.c
+++ b/ntoskrnl/mm/ARM3/pool.c
@@ -680,8 +680,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
     //
     // Allocations of less than 4 pages go into their individual buckets
     //
-    i = SizeInPages - 1;
-    if (i >= MI_MAX_FREE_PAGE_LISTS) i = MI_MAX_FREE_PAGE_LISTS - 1;
+    i = min(SizeInPages, MI_MAX_FREE_PAGE_LISTS) - 1;
 
     //
     // Loop through all the free page lists based on the page index
@@ -738,8 +737,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
                 if (FreeEntry->Size != 0)
                 {
                     /* Check which list to insert this entry into */
-                    i = FreeEntry->Size - 1;
-                    if (i >= MI_MAX_FREE_PAGE_LISTS) i = 
MI_MAX_FREE_PAGE_LISTS - 1;
+                    i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
 
                     /* Insert the entry into the free list head, check for 
prot. pool */
                     if (MmProtectFreedNonPagedPool)
@@ -1176,11 +1174,11 @@ MiFreePoolPages(IN PVOID StartingVa)
         }
 
         //
-        // Check if the entry is small enough to be indexed on a free list
+        // Check if the entry is small enough (1-3 pages) to be indexed on a 
free list
         // If it is, we'll want to re-insert it, since we're about to
         // collapse our pages on top of it, which will change its count
         //
-        if (FreeEntry->Size < (MI_MAX_FREE_PAGE_LISTS - 1))
+        if (FreeEntry->Size < MI_MAX_FREE_PAGE_LISTS)
         {
             /* Remove the item from the list, depending if pool is protected */
             if (MmProtectFreedNonPagedPool)
@@ -1196,8 +1194,7 @@ MiFreePoolPages(IN PVOID StartingVa)
             //
             // And now find the new appropriate list to place it in
             //
-            i = (ULONG)(FreeEntry->Size - 1);
-            if (i >= MI_MAX_FREE_PAGE_LISTS) i = MI_MAX_FREE_PAGE_LISTS - 1;
+            i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
 
             /* Insert the entry into the free list head, check for prot. pool 
*/
             if (MmProtectFreedNonPagedPool)
@@ -1228,8 +1225,7 @@ MiFreePoolPages(IN PVOID StartingVa)
         //
         // Find the appropriate list we should be on
         //
-        i = FreeEntry->Size - 1;
-        if (i >= MI_MAX_FREE_PAGE_LISTS) i = MI_MAX_FREE_PAGE_LISTS - 1;
+        i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
 
         /* Insert the entry into the free list head, check for prot. pool */
         if (MmProtectFreedNonPagedPool)

Reply via email to