June 27, 2006 at 4:28 pm #5033
I’m relatively new to Windows drivers, especially the KMDF.
(However, so far I find it much nicer than WDM.)
I’m trying to set up my driver so that I can have the read routine (EvtIoRead) wait for new data from a PCI card, which is actually read during an interrupt service routine.
So, I use IoCreateNotificationEvent, and store the PKEVENT in my device extension object. (I’ve also tried KeInitializeEvent instead, with similar results.)
In my ISR, I read some data through memory-mapped I/O, and then call KeSetEvent. (The “wait” argument is set to FALSE.) In EvtIoRead, I have a corresponding KeWaitForSingleObject, followed by KeClearEvent.
However, I’ve found this is leading to deadlocks. (Not every time, but sometimes.)
My ISR runs at DIRQL, while EvtIoRead runs at PASSIVE.
Is there a better way to set up this kind of notification structure?
I realize it’s possible that it’s related to pageable vs. non-pageable code, but my KEVENT object is contained in my device extension, which I assumed is not paged out. Maybe I am wrong about this. If so, how to I set up an event object that is not paged out and safe to set from an interrupt handler?
Thanks!June 28, 2006 at 9:44 pm #6073
Hm, let me reiterate my problem differently.
I have a simple KMDF PCI driver with an EvtIoRead routine.
In this routine, instead of actually performing an I/O read, it simple enables interrupts, so that the ISR can execute and the actual I/O is performed in the ISR’s DPC. Naturally, I want to block in EvtIoRead until the interrupt has occurred.
I have found that if I put a counter in my device context, which is incremented by my DPC, and have the EvtIoRead function wait on this boolean using a busywait, then everything occurs as I expect. The time interval between reads is similar to my interrupt time interval.
However, obviously I do not wish to include a busywait in my driver. So I’d rather use a notification event. However, simply putting a call to KeSetEvent() in my code exactly where I increase this counter, it sometimes works, but eventually at some point, after a few thousand fread() calls to the driver, my entire computer hangs — deadlock.
The documentation says that deadlock can be a problem if KeSetEvent has its Wait parameter set to TRUE. However, I am setting it to FALSE.
I understood that KeSetEvent was exactly designed for signaling an I/O routine from an interrupt handler, so I don’t understand what I’m doing wrong. An error message would be nice, but instead I get a deadlock with no messages in the debugger.
My KEVENT object, by the way, is stored in my device context.
I am going to try using a synchronization event instead of a notification event to see if that helps.
You must be logged in to reply to this topic.