A wait operation, or yield was attempted from a DPC routine

I try not to use OSR like a reference book, but I’ve been wrestling with this issue for a few days now. I am constructing my own IRP for an IRP_MJ_READ from my IoCompletion method (to read from a disk file I zwCreateFile’d earlier) . I use IoAllocateIrp. And no matter what I do I get one of two errors. But mainly I get:

ATTEMPTED_SWITCH_FROM_DPC (b8)
A wait operation, attach process, or yield was attempted from a DPC routine.
Due to: ExAcquireFastMutex at top of call stack.

It is definitely caught with my driver in the call stack, from when I IoCallDriver with that IRP I created.

I tried with and without FILE_NO_INTERMEDIATE_BUFFERING creation option in zwCreateFile. I tried with and without setting minor function to IRP_MN_DPC. I tried with and without setting irp->Flags = IRP_DEFER_IO_COMPLETION | IRP_READ_OPERATION.
I tried using irp->UserBuffer. I tried instead just creating a mdl. I always use non-paged memory in all my tests so far.

What gives? What is the special trick for creating an IRP from dispatch level and calling IoCallDriver so the lower driver does not attempt to either allocate paged memory or enter a mutex.

How about a callstack and the output of !analyze -v? if you are going through the file system I am pretty sure you can only send io at passive level, dispatch level io through the FS is for the paging path only … but I could easily be mistaken here

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@swbell.net
Sent: Tuesday, September 16, 2008 11:17 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] A wait operation, or yield was attempted from a DPC routine

I try not to use OSR like a reference book, but I’ve been wrestling with this issue for a few days now. I am constructing my own IRP for an IRP_MJ_READ from my IoCompletion method (to read from a disk file I zwCreateFile’d earlier) . I use IoAllocateIrp. And no matter what I do I get one of two errors. But mainly I get:

ATTEMPTED_SWITCH_FROM_DPC (b8)
A wait operation, attach process, or yield was attempted from a DPC routine.
Due to: ExAcquireFastMutex at top of call stack.

It is definitely caught with my driver in the call stack, from when I IoCallDriver with that IRP I created.

I tried with and without FILE_NO_INTERMEDIATE_BUFFERING creation option in zwCreateFile. I tried with and without setting minor function to IRP_MN_DPC. I tried with and without setting irp->Flags = IRP_DEFER_IO_COMPLETION | IRP_READ_OPERATION.
I tried using irp->UserBuffer. I tried instead just creating a mdl. I always use non-paged memory in all my tests so far.

What gives? What is the special trick for creating an IRP from dispatch level and calling IoCallDriver so the lower driver does not attempt to either allocate paged memory or enter a mutex.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

thanks for asking! my driver is dfsfilter.sys. Here it is.
1: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

ATTEMPTED_SWITCH_FROM_DPC (b8)
A wait operation, attach process, or yield was attempted from a DPC routine.
This is an illegal operation and the stack track will lead to the offending
code and original DPC routine.
Arguments:
Arg1: 00000000
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000

Debugging Details:

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xB8

LAST_CONTROL_TRANSFER: from 80544fdb to 804f9eee

STACK_TEXT:
ba4db908 80544fdb 000000b8 ffffffff 00000202 nt!KeBugCheck+0x14
ba4db918 80544de7 ba4db930 806e4952 0000003d nt!ScPatchFxe+0x46
ba4db928 806e4d43 ba4dba64 806e4952 badb0d00 nt!KiDispatchInterrupt+0xa7
ba4db928 806e4952 ba4dba64 806e4952 badb0d00 hal!HalpDispatchInterrupt+0xbb
ba4db9a0 b9e1a238 886a7008 ba4dba84 00000000 hal!ExAcquireFastMutex+0x12
ba4dba64 b9e1a016 888b4d30 886a7008 00000001 Ntfs!NtfsCommonRead+0x6aa
ba4dbb04 804ef163 8a5ce020 886a7008 8a5c84c8 Ntfs!NtfsFsdRead+0x22d
ba4dbb14 b9ebb459 ba4dbb60 804ef163 8a5cf950 nt!IopfCallDriver+0x31
ba4dbb1c 804ef163 8a5cf950 886a7008 886a71b4 sr!SrPassThrough+0x31
ba4dbb2c b4a852a0 00000000 888dfd28 888dfd28 nt!IopfCallDriver+0x31
ba4dbb60 b4a84883 8a27b3f0 88786768 8a5cf950 dfsfilter!MDFCreateRead+0x1a0 [c:\mdfdriver\mdfdriver.c @ 1539]
ba4dbba0 b4a84cc1 8a27b3f0 88786768 8a5cf950 dfsfilter!MDFStartNextOverflowIO+0xd3 [c:\mdfdriver\mdfdriver.c @ 1154]
ba4dbbf0 804f1694 88786768 88883008 888dfd28 dfsfilter!MDFReadDBIOCompletion+0x2f1 [c:\mdfdriver\mdfdriver.c @ 1288]
ba4dbc20 ba0e8c70 ba4dbc50 ba0e8f54 8a52bab8 nt!IopfCompleteRequest+0xa2
ba4dbc28 ba0e8f54 8a52bab8 88c37008 00000001 CLASSPNP!ClassCompleteRequest+0x11
ba4dbc50 804f1694 00000000 8870d228 8875f008 CLASSPNP!TransferPktComplete+0x180
ba4dbc80 b9ef465e 8a5cbaa0 8a5fa0e8 00000000 nt!IopfCompleteRequest+0xa2
ba4dbcac b9ef4b94 8870d228 8a5cbaa0 ba4dbd27 atapi!IdeProcessCompletedRequest+0x664
ba4dbd28 805451ff 8a5fa0a4 8a5fa030 00000000 atapi!IdePortCompletionDpc+0x204
ba4dbd50 805450e4 00000000 0000000e 00000000 nt!KiRetireDpcList+0x61

FOLLOWUP_IP:
dfsfilter!MDFCreateRead+1a0
b4a852a0 33c0 xor eax,eax

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: dfsfilter!MDFCreateRead+1a0

MODULE_NAME: dfsfilter

IMAGE_NAME: dfsfilter.sys

perhaps I should queue the work to a worker thread? I could do that. This is just not my experience from writing a TDI filter drier sitting atop TCP/IP. I did the entire driver for SQLNitro product (see dbnitro.com) and it creates IRPs out the wazoo at dispatch level. But I understand that the Windows kernel is a strange mine field. I don’t mind implementing a worker thread if needed.

The stack indicates that the FS expects passive level. The irql requirements for processing io depends on the stack. For instance, the FS requires passive, but the underlying volume or disk stacks can handle io at dispatch. To thunk back to passive you would need your own thread or a work item.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@swbell.net
Sent: Tuesday, September 16, 2008 11:48 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A wait operation, or yield was attempted from a DPC routine

perhaps I should queue the work to a worker thread? I could do that. This is just not my experience from writing a TDI filter drier sitting atop TCP/IP. I did the entire driver for SQLNitro product (see dbnitro.com) and it creates IRPs out the wazoo at dispatch level. But I understand that the Windows kernel is a strange mine field. I don’t mind implementing a worker thread if needed.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> What is the special trick for creating an IRP from dispatch level and calling IoCallDriver

so the lower driver does not attempt to either allocate paged memory or enter a mutex.

Unfortunately, none…

The very fact that you send IRP at elevated IRQL is an indication to the target driver to ensure that it cannot attempt any operations that are not allowed at elevated IRQL. However, if some crappy driver does not check it… well, I am afraid you are completely out of luck here…

Anton Bassov

In this case, the minefield is not all that strange.

TCPIP.SYS is not a file system and does not place the same constraints on
the use of its dispatch entry points. IRQL rules for IoCallDriver() depend
on the driver (stack) and the specific request IRP_MJ_xxx.

Worker thread or work item, somehow.

Good Luck,
-dave

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@swbell.net
Sent: Wednesday, September 17, 2008 2:48 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] A wait operation, or yield was attempted from a DPC
routine

perhaps I should queue the work to a worker thread? I could do that. This is
just not my experience from writing a TDI filter drier sitting atop TCP/IP.
I did the entire driver for SQLNitro product (see dbnitro.com) and it
creates IRPs out the wazoo at dispatch level. But I understand that the
Windows kernel is a strange mine field. I don’t mind implementing a worker
thread if needed.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

awesome! Thanks for the answers. I greatly appreciate it and it all makes sense.