Holding off ISR Execution

I have the following code where I buffer some packets that are to be transferred in the ISR. I have an issue where the ISR occurs between when the message data is buffered and the buffer pointers are updated. Is there any way to hold off the ISR execution while a few instructions are completed?

else if ((ReadReg(pcmcanDevContext, channel, SJA1000_IER) & IRQ_TI) && // irq enabled
(pcmcanDevContext->fXmitBufferFull[channel - 1] == WdfFalse)) // space in buffer
{
// place request in buffer for processing when irq occurs
pcmcanDevContext->xmitBuffer[channel - 1][pcmcanDevContext->xmitInPtr[channel-1]].FrameInfo =
((rwDatagramParams->type << 6) & (SJA1000_FI_FF | SJA1000_FI_RTR)) |
(rwDatagramParams->length & SJA1000_FI_DLC);

// tx id + data
pcmcanDevContext->xmitBuffer[channel - 1][pcmcanDevContext-xmitInPtr[channel - 1]].ID.EFF_ID[0] = (UCHAR)(rwDatagramParams->id >> 21) & 0xff;
pcmcanDevContext->xmitBuffer[channel - 1][pcmcanDevContext->xmitInPtr[channel - 1]].ID.EFF_ID[1] = (UCHAR)(rwDatagramParams->id >> 13) & 0xff;
pcmcanDevContext->xmitBuffer[channel - 1][pcmcanDevContext->xmitInPtr[channel - 1]].ID.EFF_ID[2] = (UCHAR)(rwDatagramParams->id >> 5) & 0xff;
pcmcanDevContext->xmitBuffer[channel - 1][pcmcanDevContext->xmitInPtr[channel - 1]].ID.EFF_ID[3] = (UCHAR)(rwDatagramParams->id << 3) & 0xf8;

for (UINT8 i = 0; i < rwDatagramParams->length; i++)
pcmcanDevContext->xmitBuffer[channel - 1][pcmcanDevContext->xmitInPtr[channel - 1]].Data[i] = (UCHAR)rwDatagramParams->msg[i];

----> interrupt occurs here

// increment xmit input pointer
pcmcanDevContext->xmitInPtr[channel - 1]++;

// reset if at end
if (pcmcanDevContext->xmitInPtr[channel - 1] == XMIT_BUFFER_SIZE)
pcmcanDevContext->xmitInPtr[channel - 1] = 0;

// clear empty flag
pcmcanDevContext->fXmitBufferEmpty[channel - 1] = WdfFalse;

// set full flag if necessary
if (pcmcanDevContext->xmitInPtr[channel - 1] == pcmcanDevContext->xmitOutPtr[channel - 1])
pcmcanDevContext->fXmitBufferFull[channel - 1] = WdfTrue;

----> would like to delay ISR processing until here

}

Look at KeSynchronizeExecution or KeRaiseIrql .

If you decide to use KeRaiseIrql you need to call it on each CPU for example from a DPC scheduled by KeGenericCallDpc , this routine is not documented but you can google for its usage examples.

I presume that for some reasons you can’t modify a driver that registers ISR routine .

KeRaiseIrql is the wrong answer. KeSynchronizeExecution or
KeAcquireInterruptSpinLock will do what you want.

Mark Roddy

On Thu, May 18, 2017 at 12:44 PM, wrote:

> Look at KeSynchronizeExecution or KeRaiseIrql .
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

It is a right answer if you know how to do this on each CPU.
KeGenericCallDpc does the trick.

Can KeAcquireInterruptSpinLock be used from within an IoDeviceControl function?

It can be called anywhere if IRQL is less or equal to ISR/Interrupt IRQL.

Thanks for the assistance. If I obtain the interrupt lock and release it, will I miss an interrupt that could occur while locked or will it be delayed until I release the lock?

Delayed.
Either APIC keeps it and triggers as soon as it is enabled OR the system holds another CPU in a loop until a spinlock released.

Ok, seriously, this is a forum for providing sensible advice on how to do
things. That is a ridiculous way to synchronize with your device isr. It
remains the wrong answer. Corralling the cpus is the right answer for some
problems, not for “how do I keep this data structure coherent with my isr?”.

Mark Roddy

On Thu, May 18, 2017 at 1:05 PM, wrote:

>


>
> It is a right answer if you know how to do this on each CPU.
> KeGenericCallDpc does the trick.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

No you aren’t going to miss an interrupt. But of course you are delaying
your interrupt processing, and that can have consequences.

Mark Roddy

On Thu, May 18, 2017 at 1:32 PM, wrote:

> Thanks for the assistance. If I obtain the interrupt lock and release it,
> will I miss an interrupt that could occur while locked or will it be
> delayed until I release the lock?
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

LOL. Keep trying.

Everybody play nice. The interrupt spin lock fixed my problem. Thanks. The small delay on the interrupt service shouldn’t be a problem.

If you insist.

Do you seriously think that “corral all the processors at DIRQL” is a good
way to serialize access to data between some arbitrary thread and an isr?

Mark Roddy

On Thu, May 18, 2017 at 2:22 PM, wrote:

>


>
> LOL. Keep trying.
>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

No. But it solves the task if nothing else available, e.g. ISR is registered by a third party driver.

>this routine is not documented but
you can google for its usage examples.

Great idea !

I can’t imagine a dev making that kind of proposition in a professional environment. He would be fired.

You are fired Slava.

J. S.

----> would like to delay ISR processing until here

Well, you need the interrupt lock because :

  1. Either you write to iospace (device register) to ask the device to stop interrupting and you must acquire the interrupt lock to do this.
  2. Or, you simply acquire the interrupt lock just to be sure the Isr doesn’t compete with you.

KMDF drivers use WdfInterruptAcquireLock.

J. S.

You have a bad imagination or never worked in a professional environment. This routine is used in many products.

BTW you will have to fire Alex Ionescu who used this routine in the SimpleVisor hypervisor.

It seems that this particular dead horse sadly deserves more beatings.

It would have simpler to just say “oops. my bad” instead, but who does
that? Instead almost all of us just keep maintaining that our position is
the correct one no matter how glaringly wrong it was.

Mark Roddy

On Fri, May 19, 2017 at 12:05 AM, wrote:

>


>
> You have a bad imagination or never worked in a professional environment.
> This routine is used in many products.
>
> BTW you will have to fire Alex Ionescu who used this routine in the
> SimpleVisor hypervisor.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

Yes. Just believe me that raising IRQL on all CPUs is a solution for some cases.