Hi folks,
I’ve been attempting to debug a memory leak for a little while, and come
to an unsavoury conclusion.
I’m testing an NDIS5 driver on 2K8. On the Rx side of things:
- I allocate packets with NdisAllocatePacket
- Chain an MDL into the packet using NdisChainBufferAtFront.
- Indicate the packet up the stack.
The one thing to note is that the MDL is not allocated using
NdisAllocateBuffer but is an MDL allocated by one of our other drivers.
I note however that NdisAllocateBuffer simply does an IoAllocateMdl
followed by an MmBuildMdlForNonPagedPool.
- Later on when the stack indicates it’s finished with the packet:
- I unchain the buffer using NdisUnchainBufferAtFront.
- I free the packet using NdisFreePacket.
Unfortunately, there’s a sizeable memory leak with the pooltag NDnd. We
have a fancy “packet recycling” algorithm, which I disabled, so that
packets are always exlicitly allocated or freed. However, the memory
leak still exists.
Investigation revealed that the most likely candidate was this allocation:
NDIS!ndisAllocateFromNPagedPool
NDIS!ndisPplAllocate+0x61
NDIS!NdisAllocateNetBufferAndNetBufferList+0x53
NDIS!ndisXlateRecvPacketArrayToNetBufferLists+0xc8
NDIS!ndisMIndicatePacketsToNetBufferLists+0x3d
sfcndis5!NICHandleRxPush+0x1ea
So it looks like the net buffer list or some associated structure
created to “encapsulate” the NDIS5 packet (which roughly translates to
an NDIS6 net buffer) is not getting freed.
I’ve checked that we free pretty much everything we allocate:
+0xc8c PacketPoolAllocs : 1
+0xc90 PacketPoolFrees : 0
+0xc94 PacketAllocs : 0x6fea1
+0xc98 PacketFrees : 0x6fe9c
+0xc9c BuffersChained : 0x6fea1
+0xca0 BuffersUnchained : 0x6fe9c
and the result of !poolused does not look good:
1: kd> !poolused 0x1 NDnd
Sorting by Tag
Pool Used:
NonPaged Paged
Tag Allocs Frees Diff Used Allocs Frees Diff
Used
NDnd 600438 90 600348 153701592 0 0
0 0
What have I forgotten? If nothing, then looks like a flaw in the wrapper.
MH.