WdfInterruptQueueDpcForIsr result when EvtInterruptIsr interrupts EvtInterruptDpc

WdfInterruptQueueDpcForIsr definition:
“WdfInterruptQueueDpcForIsr returns TRUE if it successfully queues the
interrupt object’s EvtInterruptDpc callback function. The method
returns FALSE if the callback function was previously queued and has
not executed.”

What happens if DPC callback is executing, and interrupt callback is
called and queues another DPC? For example:

EvtInterruptDpc callback started
EvtInterruptIsr callback started (interrupting DPC callback)
EvtInterruptIsr callback calls WdfInterruptQueueDpcForIsr
EvtInterruptIsr exits
EvtInterruptDpc continues
EvtInterruptDpc exits

So, if such sequence is executed, what is WdfInterruptQueueDpcForIsr
return value? More important, is another DPC queued in this case?

When you call WdfInterruptQueueDpcForIsr to queue a DpcForIsr callback, the system takes your device’s default DPC object and queues it for execution on the DPC List. If your DPC Object is already on the queue when you call WdfInterruptQueueDpcForIsr… then your request to queue the object has already been met (because the request is on the queue and the system can’t put the same Object on the queue twice).

The next time the system is ready to drop below IRQL DISPATCH_LEVEL, it checks the DPC List to see if there are any DPC Objects queued. If there are, it removes the first such Object from the DPC list and then calls the callback associated with that Object.

Soooo… given the above, you can work the rules out for yourself, I think. The rules about DpcForIsr callbacks are:

  • If you call WdfInterruptQueueDpcForIsr, and a DPC callback is already queued for your device, there’s no additional callback queued.
  • if you call WdfInterruptQueueDpcForIsr and there’s no DPC callback queued for your device, a new callback is queued.

This means:

  • Your DpcForIsr callback can run on multiple processors simultaneously
  • In terms of knowing whether a new DpcForIsr callback is queued, the only thing that matters is if there’s already a callback queued. Whether you’re running in your DpcForIsr callback or not doesn’t matter. If you’re in your DpcForIsr callback, and your ISR calls WdfInterruptQueueDpcForIsr, then if there’s no DPC Object queued for that device, it’ll queue it – If there already IS a DPC Object queued for that device, it won’t try to queue the same Object a second time.

I hope that helps,

Peter

Peter, thanks, it’s clear now.