[NTOS]
authorThomas Faber <thomas.faber@reactos.org>
Wed, 14 Sep 2016 12:45:45 +0000 (12:45 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Wed, 14 Sep 2016 12:45:45 +0000 (12:45 +0000)
- Return pool quota before freeing IRPs to a lookaside list
CORE-11962 #resolve

svn path=/trunk/; revision=72674

reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/io/iomgr/irp.c
reactos/ntoskrnl/mm/ARM3/expool.c

index be245aa..866d597 100644 (file)
@@ -1397,6 +1397,11 @@ ExpCheckPoolAllocation(
     POOL_TYPE PoolType,
     ULONG Tag);
 
     POOL_TYPE PoolType,
     ULONG Tag);
 
+VOID
+NTAPI
+ExReturnPoolQuota(
+    IN PVOID P);
+
 
 /* mmsup.c *****************************************************************/
 
 
 /* mmsup.c *****************************************************************/
 
index e243cfc..e00baf1 100644 (file)
@@ -1649,6 +1649,14 @@ IoFreeIrp(IN PIRP Irp)
         /* The free was within the Depth */
         if (Irp)
         {
         /* The free was within the Depth */
         if (Irp)
         {
+            /* Remove the association with the process */
+            if (Irp->AllocationFlags & IRP_QUOTA_CHARGED)
+            {
+                ExReturnPoolQuota(Irp);
+                Irp->AllocationFlags &= ~IRP_QUOTA_CHARGED;
+            }
+
+            /* Add it to the lookaside list */
             InterlockedPushEntrySList(&List->L.ListHead,
                                       (PSLIST_ENTRY)Irp);
         }
             InterlockedPushEntrySList(&List->L.ListHead,
                                       (PSLIST_ENTRY)Irp);
         }
index 25d3b41..503f5ea 100644 (file)
@@ -1509,6 +1509,53 @@ ExQueryPoolUsage(OUT PULONG PagedPoolPages,
     *PagedPoolLookasideHits += 0;
 }
 
     *PagedPoolLookasideHits += 0;
 }
 
+VOID
+NTAPI
+ExReturnPoolQuota(IN PVOID P)
+{
+    PPOOL_HEADER Entry;
+    POOL_TYPE PoolType;
+    USHORT BlockSize;
+    PEPROCESS Process;
+
+    if ((ExpPoolFlags & POOL_FLAG_SPECIAL_POOL) &&
+        (MmIsSpecialPoolAddress(P)))
+    {
+        return;
+    }
+
+    Entry = P;
+    Entry--;
+    ASSERT((ULONG_PTR)Entry % POOL_BLOCK_SIZE == 0);
+
+    PoolType = Entry->PoolType - 1;
+    BlockSize = Entry->BlockSize;
+
+    if (PoolType & QUOTA_POOL_MASK)
+    {
+        Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
+        ASSERT(Process != NULL);
+        if (Process)
+        {
+            if (Process->Pcb.Header.Type != ProcessObject)
+            {
+                DPRINT1("Object %p is not a process. Type %u, pool type 0x%x, block size %u\n",
+                        Process, Process->Pcb.Header.Type, Entry->PoolType, BlockSize);
+                KeBugCheckEx(BAD_POOL_CALLER,
+                             0x0D,
+                             (ULONG_PTR)P,
+                             Entry->PoolTag,
+                             (ULONG_PTR)Process);
+            }
+            ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1] = NULL;
+            PsReturnPoolQuota(Process,
+                              PoolType & BASE_POOL_TYPE_MASK,
+                              BlockSize * POOL_BLOCK_SIZE);
+            ObDereferenceObject(Process);
+        }
+    }
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
@@ -2285,7 +2332,6 @@ ExFreePoolWithTag(IN PVOID P,
     if ((Entry->PoolType - 1) & QUOTA_POOL_MASK)
     {
         Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
     if ((Entry->PoolType - 1) & QUOTA_POOL_MASK)
     {
         Process = ((PVOID *)POOL_NEXT_BLOCK(Entry))[-1];
-        ASSERT(Process != NULL);
         if (Process)
         {
             if (Process->Pcb.Header.Type != ProcessObject)
         if (Process)
         {
             if (Process->Pcb.Header.Type != ProcessObject)