I’ve got a lock-up in my (KMDF) driver and my current theory is that it
is related to my interrupt processing.
However, thinking the problem through I’m stumped on what appears to
me to be a race condition without a solution…
My ISR clears the hardware interrupt source and sets a flag in volatile
memory that can be accessed by the InterruptDPC callback to indicate
what type of interrupt (there are several) has occurred.
The InterruptDPC callback then uses WdfInterruptAcquireLock to access
the flags in order to process each of the interrupt sources. Finally it
resets the flag and then releases the interrupt lock.
Sounds OK in theory.
However, a hardware interrupt can be raised at any time, including of
course whilst the DPC is running. Obviously whilst it holds the
interrupt lock, the DPC can’t be pre-empted. But that doesn’t stop the
interrupt being serviced immediately after the lock is released, but
before the DPC has exited and been de-queued.
Problem is, the new interrupt ISR attempts to queue the DPC and it
fails. The interrupt is cleared and the flag is set, but no DPC
executes. Due to the nature of the driver, further interrupts for this
device/driver are never generated (because the DPC didn’t execute) and
the system grinds to a halt.
No amount of looping/checking in the DPC is going to overcome this basic
problem - namely that there is a window during which the DPC has
released the interrupt lock but hasn’t been dequeued, in which an
interrupt may occur which attempts to queue another DPC.
Can anyone confirm that my thinking thru of this scenario is correct? If
this is the case, then how is this general condition avoided? It appears
to me to be a fundamental problem with the single-DPC-queued mechanism
that others must have encountered before?
Or am I missing something?
Regards,
–
Mark McDougall, Engineer
Virtual Logic Pty Ltd, http:
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266</http:>