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.

Not getting all interrupts in KMDF driver

ecodevecodev Member Posts: 1

Hello,

I'm trying to port an existing linux device driver to windows. It's mostly working, but there's a weird issue - sometimes device won't interrupt or the interrupt is lost.
Interrupts are only lost when I'm not actively debugging.

My ISR and dpc look like this:

 //isr
  pDE  = xGetDeviceContext(WdfInterruptGetDevice(Interrupt));
  intrv = READ_REG_32(pDE, OFFSET_INTERRUPT_REG);
  pDE->interruptMask = READ_REG_32(pDE, OFFSET_INTERRUPT_MASK_REG);

  intrv &= pDE->interruptMask;
  if(intrv == 0){
      return FALSE;
  }
  pDE->interruptStatus |= intrv; //trying to save values in case different interrupts come too fast for dpc
  WdfInterruptQueueDpcForIsr( pDE->m_Interrupt);
//DPC
 pDE  = xGetDeviceContext(WdfInterruptGetDevice(Interrupt));
 WdfInterruptAcquireLock(Interrupt);
 nMainIntStatus = pDE->interruptStatus;
 pDE->interruptStatus = 0;
 WdfInterruptReleaseLock(Interrupt);

 if(nManIntStatus & interrupt_mask_event_1){
   KeSetEvent(&pDE->interrupt_event_1, IO_SOUND_INCREMENT, FALSE);
 }
 //and so on...
//in my code I'm waiting on pDE->interrupt_event_1:
 status = KeWaitForSingleObject(&pDE->interrupt_event_1, Executive, KernelMode, TRUE, &timeout);

I tried enabling automatic serialization in interrupt config, but this did not resolve my issue.

I'm currently out of options, I suspect either improper synchronization or that I should be using a different wait method.
Please give me any advice you could think of.

Comments

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

    Hmmmmm... did you set a breakpoint or do a DbgPrint in your ISR?

    How do you know your ISR is not firing?

    If you mean you’re not getting one DPC callback for each ISR invocation... then, that’s the way Windows works. If you follow up by saying that’s what you mean, I’ll explain further.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

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

    On, and by the way... you can not call KeSetEvent from your ISR. The IRQL is too high.

    Your design appears to have some challenges...

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,104

    You can replace these four lines:

    WdfInterruptAcquireLock(Interrupt);
    nMainIntStatus = pDE->interruptStatus;
    pDE->interruptStatus = 0;
    WdfInterruptReleaseLock(Interrupt);

    with
    nMainIntStatus = InterlockedExchange( &pDE->InterruptStatus, 0 );

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,104

    Does reading the interrupt register clear the interrupts?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • anton_bassovanton_bassov Member Posts: 5,052

    On, and by the way... you can not call KeSetEvent from your ISR. The IRQL is too high.

    Actually, the OP does not do it - the only thing that the OP does in ISR is queuing a DPC, and KeSetEvent() is already invoked by DPC routine at the time when interrupt spinlock is not held. Therefore, the OP's code seems to be correct in this respect.

    Concerning his actual question, I think it may well be just a misinterpretation of the situation. Judging from the code his has shown us in so far, he expects one-to-one correspondence between the number of interrupts and the number of times his waiting thread gets released
    (let's assume he uses two separate counters that he expects to match one another - otherwise, as you have already pointed out, he simply has no way of evaluating the situation).

    Let's assume he increments the thread counter immediately after KeWaitxxx() returns control. Now consider what happens if his interrupt fires while the target thread is on the runqueue, i.e. it had been already released but did not yet get a chance to actually get to the CPU. In this case his ISR counter (which indicates the number of times his DPC gets queued and,hence, KeSetEvent() gets invoked) is going to exceed the thread one. The OP seems to be (mis) taking this mismatch for a lost interrupt. Therefore, it seems to be just the question of the wrong interpretation....

    Anton Bassov

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