KeWaitForSingleObject() in kernel thread and KeSetEvent() in DPC leads to ATTEMPTED_SWITCH_FROM_DPC

Hi All,
This is a solved cas for your information and as i found nothing about this int the forums.

Context : Windows 10 21H1 64b.
WDM based driver.
I have a kernel thread which wait on a kernel event (KeWaitForSingleObject()). I have a DPC signaling this event.
When KeSetEvent() is called, I observed a fatal system error ATTEMPED SWITCH FROM DPC.
At first re-reading the MSDN and OSR forums leads to nothing. I’ve just found some issues with KeWaitForSingleObject() w/o time-out raising the IRQL.
But the levels were the expected ones (note: DPC ran at APC_LEVEL not DISPATCH_LEVEL).
So what was the issue ??

Solution : I follow my intuition : this is a wait w/o time-out case. Tried adding a time-out value and VOILA !! No more ATTEMPED SWITCH FROM DPC error occured.

Hope this help.
If this has already been reported, sorry for the burden.

EriC.

First of all: WHY are you posting this in the Administration section of the site? I’ve moved it to NTDEV.

Second: Your post is… mistaken… at least in part. Your DPC cannot run at IRQL APC_LEVEL.

Overall, I’m sorry to say it’s really not clear what you’re telling us here. Though I certainly appreciate your willingness to share your experience with the community.

Peter

Hi Peter,

Sorry for the wrong section, I’ve jumped onto the “New Discussion” button, the target categories are out of screen with a wide display. Now I know.

About the IRQL, I’ve just re-done the test and in the DPC, the KeGetCurrentIrql() function returns 1 ( (#define APC_LEVEL 1 // APC interrupt level). I agree this should be PASSIVE_LEVEL (2) but this is not what I’ve observed here.

The trouble is that the classic pattern of a DPC setting an event while a kernel thread is waiting on it leads to a fatal system error ATTEMPTED_SWITCH_FROM_DPC when the DPC calls stack is KeSetEvent() => KiExitDispatcher() => KiSwapContext() : ERROR.

By the way I’m affraid I was too optimistic, I still have the system error.

Regards,
Eric.

Ok, so you have some entirely other problem, as setting an event in a dpc
routine to signal a passive level thread is absolutely allowed, it is in
fact a standard practice.

I’d focus on why your dpc thread appears to be running at APC_LEVEL rather
that DISPATCH_LEVEL, that is a symptom of IRQL mismanagement and your
bugcheck is much more likely to be a result of that, as in the APC_LEVEL
allows a scheduling operation on the dpc thread and that causes the
bugcheck. Calling KeSetEvent is just the vehicle that delivers your busted
dpc thread into the hands of the ‘scheduler’.

Mark Roddy

What Mr. @Mark_Roddy said.

Your DPC can not run at APC_LEVEL. Either it’s not a DPC, or you’ve done something to cause it to lower IRQL from DISPATCH_LEVEL.

Peter

1 Like

Hi all,
Thanks for your help. At first, I was a bit disappointed, but I’ve Re-re-read the Book (Programming the Microsoft Windows Driver Model 2nd Ed.) and got the answer in chapter 4.4.1 : only spinlocks are allowed in DISPATCH_LEVEL and above.
And my design used 2 DPC potentially sharing resources. I’ve done this to allow a multi-threaded DPC processing on a muti-core CPU. Because my need is to concurently process input and output streams thus having 2 DPC. But this is perhaps a wrong solution, or at least using locked sections as small as possible on shared resources.

To know : using a dispatcher object other than a spinlock in a DPC lowers the execution level to APC_LEVEL.

Regards,
Eric.