- Return pool quota before freeing IRPs to a lookaside list
CORE-11962 #resolve

svn path=/trunk/; revision=72674
This commit is contained in:
Thomas Faber 2016-09-14 12:45:45 +00:00
parent aac3bbc746
commit 503cf310ad
3 changed files with 60 additions and 1 deletions

View file

@ -1397,6 +1397,11 @@ ExpCheckPoolAllocation(
POOL_TYPE PoolType,
ULONG Tag);
VOID
NTAPI
ExReturnPoolQuota(
IN PVOID P);
/* mmsup.c *****************************************************************/

View file

@ -1649,6 +1649,14 @@ IoFreeIrp(IN PIRP 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);
}

View file

@ -1509,6 +1509,53 @@ ExQueryPoolUsage(OUT PULONG PagedPoolPages,
*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 ***********************************************************/
/*
@ -2285,7 +2332,6 @@ ExFreePoolWithTag(IN PVOID P,
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)