MmUnlockPages() (viaIoBuildAsynchronousFsdRequest()) bugcheck

Hi All,

My FSD is being called by the lazy writer and in response my
IRP_MJ_WRITE handler ends up passing the data down to a lower driver via
an IRP built with IoBuildAsynchronousFsdRequest(). The lower driver uses
DIRECT_IO and hence it would appear IoBuildAsynchronousFsdRequest()
allocates an MDL for my buffer (which is 512kb from non-paged memory in
the context of the system process anyway) and calls
MmProbeAndLockPages() for me (is that correct?).

I simply take the IRP given back to me, use it with IoCallDriver() and
if STATUS_PENDING is returned I wait on an event to be signaled (which I
do in my completion routine for the IRP).

My buffer is shared by potentially many threads in the IRP_MJ_WRITE
handler and so is protected by an ERESOURCE – this is acquired before
using the buffer and released once the call to IoCallDriver() returns
success or failure (after waiting on a pend if necessary).

Under high system load (ie. when writing many large files to the volume
in parallel) the system bugchecks with IRQL_NOT_LESS_OR_EQUAL
(presumably due to the invalid address in EDI, trying to be touched by
MmUnlockPages() – is this part of the MDL allocated by
IoBuildAsynchronousFsdRequest()?)

Why does MmProbeAndLockPages() call MmUnlockPages() anyway?

Here is my bugcheck analysis -

(NOTE: Despite the names of some of the functions being called, the
system may or may not actually be at APC level, but will definitely be
at or BELOW APC (validated by an ASSERT()).

*******************************************************************************
*
*
* Bugcheck Analysis
*
*
*
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck A, {9a2c008c, 2, 1, 805022fa}

Probably caused by : driver.SYS (
driver!DriverSendAsyncIRPToBlockDeviceAtApcLevel+3a6 )

Followup: MachineOwner

nt!RtlpBreakWithStatusInstruction:
8051d778 cc int 3
0: kd> !analyze -v
*******************************************************************************
*
*
* Bugcheck Analysis
*
*
*
*******************************************************************************

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address
at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 9a2c008c, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: 805022fa, address which referenced memory

Debugging Details:

WRITE_ADDRESS: 9a2c008c Nonpaged pool

CURRENT_IRQL: 2

FAULTING_IP:
nt!MmUnlockPages+16e
805022fa 834f0c01 or dword ptr [edi+0xc],0x1

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xA

LAST_CONTROL_TRANSFER: from 80502a54 to 805022fa

TRAP_FRAME: f7ca4578 – (.trap fffffffff7ca4578)
ErrCode = 00000002
eax=000004c7 ebx=850905c8 ecx=04c81601 edx=00000000 esi=850905f8
edi=9a2c0080
eip=805022fa esp=f7ca45ec ebp=f7ca4604 iopl=0 nv up ei ng nz na
po cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
efl=00010287
nt!MmUnlockPages+0x16e:
805022fa 834f0c01 or dword ptr [edi+0xc],0x1
Resetting default scope

STACK_TEXT:
f7ca4604 80502a54 000905c8 00000000 863a0ec8 nt!MmUnlockPages+0x16e
f7ca4690 804ed1c4 850905c8 00000000 00000001 nt!MmProbeAndLockPages+0x66c
f7ca46d0 f37ff416 00000003 86485c78 84b28008
nt!IoBuildAsynchronousFsdRequest+0x110
f7ca47a0 f37ff387 86485c78 84c61330 f7ca481c
Driver!DriverSendAsyncIRPToBlockDeviceAtApcLevel+0x3a6
[c:\dev\driver\filesystemdriver\diskaccess.c @ 532]
f7ca4874 f37feb13 86485c78 84c61330 f7ca490c
Driver!DriverSendAsyncIRPToBlockDeviceAtApcLevel+0x317
[c:\dev\driver\filesystemdriver\diskaccess.c @ 507]
f7ca489c f38283d0 86485c78 84c61330 f7ca490c
Driver!DriverWriteBlockDeviceAtApcLevel+0x23
[c:\dev\driver\filesystemdriver\diskaccess.c @ 386]
f7ca495c f3804360 84c61330 84c6f010 8638a4a0
Driver!DriverWritePfFrameToMovie+0xad0
[c:\dev\driver\filesystemdriver\pfs.c @ 1560]
f7ca49d0 f38232d9 84c61330 84c6f010 f7ca4a8c
Driver!DriverWriteFileData+0x300 [c:\dev\driver\filesystemdriver\write.c
@ 934]
f7ca4ac4 f3821d16 86352470 00000001 00000001
Driver!DriverWriteNormal+0xc49 [c:\dev\driver\filesystemdriver\write.c @
586]
f7ca4adc f380fef8 86352470 00000004 00000001 Driver!DriverWrite+0xe6
[c:\dev\driver\filesystemdriver\write.c @ 73]
f7ca4af8 f380fbce 86352470 8638a4a0 863e0a18
Driver!DriverDispatchRequest+0x148
[c:\dev\driver\filesystemdriver\dispatch.c @ 215]
f7ca4b38 804eb3c1 84c61278 86369008 007d0000
Driver!DriverBuildRequest+0xee
[c:\dev\driver\filesystemdriver\dispatch.c @ 149]
f7ca4b48 804ec4b9 f7ca4d58 f7ca4b84 00000000 nt!IopfCallDriver+0x31
f7ca4b5c 80506d61 8638a402 f7ca4b84 f7ca4c18 nt!IoSynchronousPageWrite+0xad
f7ca4c34 805076ec e1423f40 e1423f80 00000000 nt!MiFlushSectionInternal+0x399
f7ca4c70 804e11cf 863d4e78 000007d0 00010000 nt!MmFlushSection+0x1c4
f7ca4cf8 804e1539 00010000 00000000 00000001 nt!CcFlushCache+0x37d
f7ca4d3c 804e3bf3 867b81e0 8054d1a0 867b7340 nt!CcWriteBehind+0x133
f7ca4d7c 80528545 867b81e0 00000000 867b7340 nt!CcWorkerThread+0x11f
f7ca4dac 805b05c6 867b81e0 00000000 00000000 nt!ExpWorkerThread+0xed
f7ca4ddc 80534de6 80528458 00000000 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

FOLLOWUP_IP:
Driver!DriverSendAsyncIRPToBlockDeviceAtApcLevel+3a6
[c:\dev\driver\filesystemdriver\diskaccess.c @ 532]
f37ff416 8945d0 mov [ebp-0x30],eax

SYMBOL_STACK_INDEX: 3

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: Driver!DriverSendAsyncIRPToBlockDeviceAtApcLevel+3a6

MODULE_NAME: Driver

IMAGE_NAME: driver.SYS

DEBUG_FLR_IMAGE_TIMESTAMP: 425dfbec

STACK_COMMAND: .trap fffffffff7ca4578 ; kb

FAILURE_BUCKET_ID:
0xA_W_Drvier!DriverSendAsyncIRPToBlockDeviceAtApcLevel+3a6

BUCKET_ID: 0xA_W_Driver!DriverSendAsyncIRPToBlockDeviceAtApcLevel+3a6

Followup: MachineOwner

------------------------------------------- 8< ------------------------

Could it be a stack overflow? I release things are getting a little
banked up in that call stack. (The recursive call is to satisfy an
unaligned write – I need to read the surrounding region).

Any help would be greatly appreciated,

Cheers,
Josh