Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Sept/Oct 2019 Issue of The NT Insider available


Download PDF here: http://insider.osr.com/2019/ntinsider_2019_01.pdf

It’s a particularly BIG issue, too: 40 pages of technical goodness, ranging from WDF to Minifilters. Check it out.
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

WdfInterruptTryToAcquireLock() vs WdfInterruptAcquireLock()

omriomri Member Posts: 16

Hey All,
Is it possible to use WdfInterruptAcquireLock() instead of WdfInterruptTryToAcquireLock() in a KMDF driver if you are not using passive interrupt handling (WDF_INTERRUPT_CONFIG::PassiveHandling == FALSE)? The docs are pretty clear on passive interrupt handling, but pretty fuzzy without passive interrupt handling. I've tried WdfInterruptTryToAcquireLock() in a EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL callback and it consistently fails and I have to resort to a work item which seems pretty excessive for just setting 1 little variable shared between multiple callbacks.
I need all this to synchronize data between an EVT_WDF_INTERRUPT_ISR, an EVT_WDF_INTERRUPT_DPC and EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL. For context, the EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL basically blocks the calling user space thread until a hardware event is triggered, the EVT_WDF_INTERRUPT_ISR is triggered by the hardware which sets a flag on a shared variable and queues up the EVT_WDF_INTERRUPT_DPC via WdfInterruptQueueDpcForIsr() that completes the original blocking EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL request using WdfRequestComplete().
Thanks!

Comments

  • anton_bassovanton_bassov Member Posts: 5,052

    The docs are pretty clear on passive interrupt handling, but pretty fuzzy without passive interrupt handling

    Well, I don't really know what you mean by " fuzzy" in this context, but let's look at the following MSDN article

    https://msdn.microsoft.com/library/windows/hardware/ff547340

    It starts right with the following line

    [begin quote]

    The WdfInterruptAcquireLock method begins a code sequence that executes at the device's device interrupt request level (DIRQL) while holding an interrupt object's spin lock.

    [end quote]

    In other words, the official documentation seems to be VERY clear and precise on this matter, don't you think - it makes it clear that WdfInterruptAcquireLock() is perfectly usable by the drivers that handle interrupts at DIRQL. Furthermore, the documentation makes it clear the same thing does NOT apply to WdfInterruptTryToAcquireLock()

    https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdfinterrupt/nf-wdfinterrupt-wdfinterrupttrytoacquirelock

    [begin quote]

    Drivers that use passive-level interrupt handling call WdfInterruptTryToAcquireLock to start a code sequence that executes at IRQL = PASSIVE_LEVEL while holding the passive-level interrupt lock that the driver configured in the interrupt object's WDF_INTERRUPT_CONFIG structure.

    [end quote]

    The "only" question that may possibly arise at this point is "WTF does the OP want to call WdfInterruptTryToAcquireLock() if his driver does not use passive-level interrupt handling, in the first place???"......

    Anton Bassov

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,443

    Just use WdfInterrupAcquireLock... it’s what we all do.

    the EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL basically blocks the calling user space thread until a hardware event is triggered

    That’s not a very good driver design in the world of Windows. First, your EvtDeviceControl is called in an arbitrary process/thread context. So if you blockmthere, you can’t be certain what thread you’re blocking. And, even if you are blocking the thread that sent the Request to you, that’s generally considered bad practice.

    Doing this then”right” way (what would be the Windows way) is easy. Just start the Request in EvtDeviceControl... do not complete it. Instead, save the Request handle someplace (you could put it in a variable in your Device context, or put it in a WDF Queue.... then, after the interrupt, in your DPC, simply come,etc the Request.

    The calling thread sends the Device Control synchronously, and doesn’t continue running until it’s completed. Quite easy, right?

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • omriomri Member Posts: 16

    OK, thanks I went ahead and ditched the work item and am just using WdfInterrupAcquireLock().
    Peter, thanks but that is what I'm doing, I probably just didn't phrase it well. I have a variable set by the ISR to indicate the hardware event triggered. In the EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL I acquire the interrupt lock and check this variable. If it's set I just call WdfRequestComplete() right there and if not I store this WDFREQUEST and call WdfRequestMarkCancelableEx(). in the interrupt's DPC I acquire the interrupt lock and if the variable is set, I call WdfRequestComplete() on the stored WDFREQUEST. So the request may complete immediately if the hardware already triggered or later via the DPC.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Writing WDF Drivers 21 Oct 2019 OSR Seminar Space & ONLINE
Internals & Software Drivers 18 Nov 2019 Dulles, VA
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 27 Apr 2020 OSR Seminar Space & ONLINE