none
Modifying InterruptConfig.InterruptTranslated->u.Interrupt.Level before creating the interrupt object in WDF RRS feed

  • Question

  • Hi All,

    In WDM during IoConnectInterrupt() we can specify the SyncIRQL. In WDF how do specify the SyncIRQL level?

    Could any one please clarify.

    I got some idea, i have to do the below modification:

    interruptConfig.InterruptTranslated->u.Interrupt.Level = HIGH_LEVEL;

    Am i correct?

    Wednesday, August 20, 2014 6:44 AM

All replies

  • You should never specify a SyncIrql of HIGH_LELVEL, the rule is you specify the max of the two IRQL's that the hardware needs. 

    So before we go into how to manage two interrupts together, tell us what is the real problem you are trying to solve?


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 20, 2014 10:45 AM
  • Hi Doron,

    I already discussed my problem with this forum. Here is the link for that:

    http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/eea9301c-f618-44f4-875e-94980eda2a16/checking-dirql-value-before-acquiring-the-interrupt-spin-lock?forum=wdk

    Just i wanted to confirm how do raise IRQL in WDF driver, so that i started new discussion.


    • Edited by Selva.S Wednesday, August 20, 2014 11:31 AM
    Wednesday, August 20, 2014 11:28 AM
  • This isn't Doron, but the bottom line is that your design is WRONG.  The previous post had Doron pointing out you needed to have more context so you could do this correctly.  

    Step back an look at the whole problem.


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 20, 2014 12:10 PM
  • Hi Don,

    Please clarify this: 

    How do we specify the SyncIRQl for interrupt object in WDF driver?

    Wednesday, August 20, 2014 12:48 PM
  • Clarify your design, there should be a better way to do the whole model.  This is what people have been trying to tell you.


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 20, 2014 1:11 PM
  • Hi Don, 

    My driver is exporting some function to other drivers. This exported function access some registers. The same registers are also accessed by my driver IO functions.

    The other driver is invoking the functions after raising the IRQL to high_level. It is a performance monitor interrupt driver. And they don't have any interrupt object, they are simply raising the IRQL using KeRaiseIRQL. It is WDM based legacy driver.

    Now i have to synchronize the access between the exported function reg access with my Io function reg access.

    This is the problem i am trying to solve.

    Wednesday, August 20, 2014 1:19 PM
  • Well the performance driver sounds like it has problems.  Is there a requirement for HIGH_LEVEL, or could the DIRQL of the other driver be good enough?  In the later case you could raise to that DIRQL and then have the other function do the KeSynchronizeExecution.

    Otherwise I think your ownly option is create your own HIGH_LEVEL spinlock in the KMDF driver.  This would be use the IRQL functions and InterlockedExchange, then use that lock for all accesses to those registers.  Just be sure you respect lock heirarchy.


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 20, 2014 1:44 PM
  • you can choose not to use a WDFINTERRUPT and manage the interrupt on your own with wdm APIs if you can't specify sync irql

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, August 20, 2014 2:06 PM
  • Could you please provide an example or the API for this

    ---------------------------snip-----------------------------

    Otherwise I think your ownly option is create your own HIGH_LEVEL spinlock in the KMDF driver.  This would be use the IRQL functions and InterlockedExchange, then use that lock for all accesses to those registers.  Just be sure you respect lock heirarchy.

    ------------------------- end --------------------------


    • Edited by Selva.S Wednesday, August 20, 2014 4:46 PM
    Wednesday, August 20, 2014 4:25 PM
  • Is it like this:

             KeRaiseIrql(HIGH_LEVEL)

             if (InterlockedExchange)

            {         } 

    One more question is even if i use "InterlockedExchange", this will return immediately without waiting.

    Wednesday, August 20, 2014 4:46 PM
  • I've used something like:

    VOID XXXAcquireSpinLock(IN PKSPIN_LOCK SpinLock,OUT PKIRQL OldIrql)
    {
          KIRQL irql;

          if (KeGetCurrentIrql() != HIGH_LEVEL)
         {
              KeRaiseIrql( DIOS_HIGH_LEVEL, OldIrql);
         }
         else
        {
             *OldIrql = HIGH_LEVEL;
         }
         while(InterlockedExchange(SpinLock,1)) {}
    }

    VOID XXXReleaseSpinLock (IN PKSPIN_LOCK SpinLock,IN KIRQL NewIrql)
    {
          KIRQL irql = KeGetCurrentIrql();

          InterlockedExchange(SpinLock,0);
          if (NewIrql != HIGH_LEVEL)
         {
             KeLowerIrql(NewIrql);
         }
    }


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 20, 2014 4:56 PM
  • Thanks Don.

    Even this was my first idea. But somehow it tracked to me to the interrupt object and finally came to this method.

    -------------- My question -------------
    Can i use Interlocked operation to check variable 0 or 1 in a while loop after raising the IRQL?

    Ref Title: Checking DIRQL value before acquiring the interrupt spin lock
    -------------------- end ----------------

    BTW, you have specified SPIN_LOCK variable to the InterlockedExchange() function. Will it work? Or i have to specify a volatile variable as the argument.
    Wednesday, August 20, 2014 5:20 PM
  • don't create your own spinlocks. If you want to use a spinlock not tied to dispatch level NOR tied to an interrupt, use KeAcquireSpinLockAtDpcLevel // KeReleaseSpinLockFromDpcLevel. this gives you a spin lock not tied to an IRQL value without having roll your own implementation

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, August 20, 2014 10:25 PM
  • My Driver IO function access the registers at PASSIVE_LEVEL and the exported function access it at HIGH_LEVEL. So i have to mix both the above solution given by Doran and Don.

    VOID XXXAcquireSpinLock(IN PKSPIN_LOCK SpinLock,OUT PKIRQL OldIrql)
    {
          KIRQL irql;

          if (KeGetCurrentIrql() != HIGH_LEVEL)
         {
              KeRaiseIrql( DIOS_HIGH_LEVEL, OldIrql);
         }
         else
        {
             *OldIrql = HIGH_LEVEL;
         }
         KeAcquireSpinLockAtDpcLevel(SpinLock); 
    }

    VOID XXXReleaseSpinLock (IN PKSPIN_LOCK SpinLock,IN KIRQL NewIrql)
    {
          KIRQL irql = KeGetCurrentIrql();

          KeReleaseSpinLockFromDpcLevel(SpinLock);

          if (irql > NewIrql) -----------> Changed the check for IRQL
         {
             KeLowerIrql(NewIrql);
         }
    }

    Is this the correct solution?

    Thursday, August 21, 2014 4:19 AM
  • Doron,

        Interesting the recommendation is to now use KeAcquireSpinLockAtDpcLevel // KeReleaseSpinLockFromDpcLevel when I originally wrote that code back in the NT 3.5 days, we tried to use these calls and folks from Redmond said that we should not.  It has been too long, but I believe there even was an ASSERT in the checked build that failed if you were not at DISPATCH_LEVEL.


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com

    Thursday, August 21, 2014 11:07 AM