I have a PTE leak problem. I’m developing a mini-filter that has the code
below in the pre-write callback. The problem shows up when a user-app does
a lot of writes, but I suspect the leak is always there but small. I doubt
the leak comes from the user-app.
Am I missing code to release a pte created by the
MmGetSystemAddressForMdlSafe call? I assume MmGetSystemAddressForMdlSafe
creates a PTE and I wonder how that PTE is expected to go away later.
Any help would be greatly appreciated…
<---- mini-filter pre-write callback code snippet ---->
if ( Data->Iopb->Parameters.Write.MdlAddress != NULL ) {
buffer = ( Data->Iopb->Parameters.Write.MdlAddress,
NormalPagePriority );
if ( buffer == NULL ) {
CpsPrint( “Unable to get sys addr in pre-write”);
goto err;
}
} else
buffer = Data->Iopb->Parameters.Write.WriteBuffer;
__try {
RtlCopyMemory( pRec->Data, buffer, dataSize );
} __except ( EXCEPTION_EXECUTE_HANDLER ) {
CpsPrint( “Exception while copying data buffer in pre-write” );
goto err;
}
> Am I missing code to release a pte created by the
MmGetSystemAddressForMdlSafe call? I assume ?
MmGetSystemAddressForMdlSafe
creates a PTE and I wonder how that PTE is expected to go away later.
If the MDL was created using MmBuildMdlForNonPagedPool, then
MmGetSystemAddressForMdlSafe is a no-op, and no PTEs are allocated.
If the MDL was created using MmProbeAndLockPages, then you must do
MmUnlockPages, and this will free the PTEs by MmUnmapLockedPages. Note that for
Irp->MdlAddress the IO manager does this automatically.
If the MDL was created using IoBuildPartialMdl, then you must later call
IoFreeMdl or at least MmPrepareMdlForReuse on it, and this frees the PTEs for
such a case.
There are no other ways of creating the MDLs besides these three. Or, yes,
there is also MmAllocatePagedForMdl, but it has its reciprocal too which will
also free the PTEs if they were allocated for a mapping.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
I remember once I had the same problem.
Long ago, my driver used MmMapLockedPages to get the
address of the buffer from MDL. When switched to Win2000,
I needed to change it for MmMapLockedPagesSpecifyCache.
When I did this, I’ve got memory leak after a lot of wites
(about half an hour while performing a very brutal copying
of some directory with installation CDs),
I’ve ran out of memory at the point where the driver
called MmMapLockedPagesSpecifyCache.
I looked into the MmMapLockedPages (this is actually only
a wrapper for the “SpecifyCache” version), there is
HighPagePriority used. I changed to that, and since then
I have no problem.
Try this, do some damn big amount of file writes and you’ll
see if the problem dissappears or not. And please, let me know
if this worked, I would like to know the result.
L.
I’m NOT using MmBuildMdlForNonPagedPool, MmProbeAndLockPages, or
IoBuildPartialMdl. My code is in a pre-write callback from the filter
manager and the memory address is provided in
Data->Iopb->Parameters.Write.MdlAddress. I assume that I don’t have to do
anything about locking or unloocking. Is this correct?
Note that for Irp->MdlAddress the IO manager does this automatically.
So my assumption is correct?
Again, my memory access code is:
if ( Data->Iopb->Parameters.Write.MdlAddress != NULL ) {
buffer = MmGetSystemAddressForMdlSafe(
Data->Iopb->Parameters.Write.MdlAddress, NormalPagePriority );
if ( buffer == NULL ) {
CpsPrint( “Unable to get sys addr in PreWrite”);
goto err;
}
} else
buffer = Data->Iopb->Parameters.Write.WriteBuffer;
“Maxim S. Shatskih” wrote in message
news:xxxxx@ntfsd…
>> Am I missing code to release a pte created by the
>> MmGetSystemAddressForMdlSafe call? I assume ?
>>MmGetSystemAddressForMdlSafe
>> creates a PTE and I wonder how that PTE is expected to go away later.
>
> If the MDL was created using MmBuildMdlForNonPagedPool, then
> MmGetSystemAddressForMdlSafe is a no-op, and no PTEs are allocated.
>
> If the MDL was created using MmProbeAndLockPages, then you must do
> MmUnlockPages, and this will free the PTEs by MmUnmapLockedPages. Note
> that for
> Irp->MdlAddress the IO manager does this automatically.
>
> If the MDL was created using IoBuildPartialMdl, then you must later call
> IoFreeMdl or at least MmPrepareMdlForReuse on it, and this frees the PTEs
> for
> such a case.
>
> There are no other ways of creating the MDLs besides these three. Or, yes,
> there is also MmAllocatePagedForMdl, but it has its reciprocal too which
> will
> also free the PTEs if they were allocated for a mapping.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
>
> if ( Data->Iopb->Parameters.Write.MdlAddress != NULL ) {
buffer = MmGetSystemAddressForMdlSafe(
Data->Iopb->Parameters.Write.MdlAddress, NormalPagePriority );
So, you map a FltMgr-provided MDL and this creates the PTE leaks? I would
really suspect a FltMgr issue here.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
> So, you map a FltMgr-provided MDL and this creates the PTE leaks? I would
really suspect a FltMgr issue here.
Now that I understand I’m not responisble for closing or unlocking anything,
I suspect kernel code has nothing to do with the problem. Blaming the
filter manager has always been wrong before. 
So now I have to figure out how my user-level code that does all the reading
and writing of 100,000 to 200,000 files/folders is causing the leak. Can
someone point me to a good place to ask questions about things like PTEs
interacting with user-code?
“Maxim S. Shatskih” wrote in message
news:xxxxx@ntfsd…
>> if ( Data->Iopb->Parameters.Write.MdlAddress != NULL ) {
>> buffer = MmGetSystemAddressForMdlSafe(
>> Data->Iopb->Parameters.Write.MdlAddress, NormalPagePriority );
>
> So, you map a FltMgr-provided MDL and this creates the PTE leaks? I would
> really suspect a FltMgr issue here.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
>
Mark
You say you have a pte leak problem but … well perhaps and perhaps not …
how do you *know* that you have a pte leak problem?
Cheers
Lyndon
“Mark Hahn” wrote in message news:xxxxx@ntfsd…
>I have a PTE leak problem. I’m developing a mini-filter that has the code
>below in the pre-write callback. The problem shows up when a user-app does
>a lot of writes, but I suspect the leak is always there but small. I doubt
>the leak comes from the user-app.
>
> Am I missing code to release a pte created by the
> MmGetSystemAddressForMdlSafe call? I assume MmGetSystemAddressForMdlSafe
> creates a PTE and I wonder how that PTE is expected to go away later.
>
> Any help would be greatly appreciated…
>
> <---- mini-filter pre-write callback code snippet ---->
>
> if ( Data->Iopb->Parameters.Write.MdlAddress != NULL ) {
> buffer = ( Data->Iopb->Parameters.Write.MdlAddress,
> NormalPagePriority );
> if ( buffer == NULL ) {
> CpsPrint( “Unable to get sys addr in pre-write”);
> goto err;
> }
> } else
> buffer = Data->Iopb->Parameters.Write.WriteBuffer;
> __try {
> RtlCopyMemory( pRec->Data, buffer, dataSize );
> }__except ( EXCEPTION_EXECUTE_HANDLER ) {
> CpsPrint( “Exception while copying data buffer in pre-write” );
> goto err;
> }
>
>