KeSetEvent + ISR/DPC...

Hello,

I seem to have a problem with concurrent applications using my driver on a Core Quad.

To solve this issue, I used a critical section (KeSynchronizeExecution) to access specific adress in my I/O. This raises the IRQ to my Interrupt IRQL thus solving one of the problem with my I/O and ISR.

My ISR gets the interrupt source and queues it to a DPC routine. My DPC routine will then raise a user Event with KeSetEvent(). The problem occurs because of the DPC IRQ. It is too low and a critical section thread runs over it.

My ISR is called, gets a value queued for the DPC but another thread takes over the processor with his KeSynchronizeExecution command and my DPC routine only gets called 4-5 sec later. I know the KeSetEvent cannot be used in the ISR. The DPC runs at DISPATCH_LEVEL but my critifical section prevents it from executing as soon as my ISR is finished.

I need to notify a user application with a user event before the critical section takes over after the ISR. Is there any way to do this?
Frederick Guillemot


Introducing the City @ Live! Take a tour!
http://getyourliveid.ca/?icid=LIVEIDENCA006

DPC always run at DISPATCH_LEVEL it is impossible for it to be TOO LOW, just
that you have designed things poorly. Why do you need to notify the
application, before someone else get at the device registers? You should be
saving all the information you need at interrupt time, then let the DPC do
what it wants.

Give us a description of what the heck you are trying to do (not set an
event, but why the event is important, what the application is going to do,
what the critical section does, etc).


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

“Frederick Guillemot” wrote in message
news:xxxxx@ntdev…

Hello,

I seem to have a problem with concurrent applications using my driver on a
Core Quad.

To solve this issue, I used a critical section (KeSynchronizeExecution) to
access specific adress in my I/O. This raises the IRQ to my Interrupt IRQL
thus solving one of the problem with my I/O and ISR.

My ISR gets the interrupt source and queues it to a DPC routine. My DPC
routine will then raise a user Event with KeSetEvent(). The problem occurs
because of the DPC IRQ. It is too low and a critical section thread runs
over it.

My ISR is called, gets a value queued for the DPC but another thread takes
over the processor with his KeSynchronizeExecution command and my DPC
routine only gets called 4-5 sec later. I know the KeSetEvent cannot be used
in the ISR. The DPC runs at DISPATCH_LEVEL but my critifical section
prevents it from executing as soon as my ISR is finished.

I need to notify a user application with a user event before the critical
section takes over after the ISR. Is there any way to do this?
Frederick Guillemot
_________________________________________________________________
Introducing the City @ Live! Take a tour!
http://getyourliveid.ca/?icid=LIVEIDENCA006

Hello,

To answer your questions:

  • The applications send I/O commands to the driver. I have limited the amount of commands with a mutex to 1.
  • Sometimes Interrupts on the card occur. They are used by the user application to do processing and calculations (I have no clue at the specific) but the interrupts need to be treated by the druver in a maximum time of 1s. Some applications send a I/O control to write a byte at 0x5. The card mechanism automaticly generates an interrupt and it caught by my ISR.

The problem occurs when we run our Testing software. Two threads are used. Thread1 writes to 0x5 to generate Interrupt and waits for the UserEvent. It calculates time…Thread2 will make a I/O to WriteByte continuasouly.

What happens is that Thread1 writes byte (so critical section occurs). ISR runs and queues to DPC. Thread 2 gets control and does X WriteByte in a row (critical sections here) before the DPC routine gets called. It results in a > 1sec delay between the 0x5 Write byte and the Application notified.

The critical section used is:

void WriteByte(Addr, ByteToBeWritten)
{

  • Write ModuleRoutingByte to Address (0x1D)
  • Write ByteToBeWritten to Addr
    }====

The ISR routine:

void MyISR()
{

  • ModuleRoutingByte = Read from Address 0x1D
  • Read ModuleThatDidInterrupt
  • Write ModuleThatDidInterrupt to Address 0x1D
  • Remove Interrupt
  • Write ModuleRoutingByte to Address (0x1D)

QueueToDpc(ModuleThatDidInterrupt)
}

The DPC routine:

void MyISR()
{
KeSetEvent(UserEvent);
}

From: xxxxx@acm.org> Subject: Re:[ntdev] KeSetEvent + ISR/DPC…> Date: Thu, 6 Dec 2007 15:24:54 -0500> To: xxxxx@lists.osr.com> > DPC always run at DISPATCH_LEVEL it is impossible for it to be TOO LOW, just > that you have designed things poorly. Why do you need to notify the > application, before someone else get at the device registers? You should be > saving all the information you need at interrupt time, then let the DPC do > what it wants.> > Give us a description of what the heck you are trying to do (not set an > event, but why the event is important, what the application is going to do, > what the critical section does, etc).> > > – > Don Burn (MVP, Windows DDK)> Windows 2k/XP/2k3 Filesystem and Driver Consulting> Website: http://www.windrvr.com> Blog: http://msmvps.com/blogs/WinDrvr\> Remove StopSpam to reply> > > > “Frederick Guillemot” wrote in message > news:xxxxx@ntdev…> > Hello,> > I seem to have a problem with concurrent applications using my driver on a > Core Quad.> > To solve this issue, I used a critical section (KeSynchronizeExecution) to > access specific adress in my I/O. This raises the IRQ to my Interrupt IRQL > thus solving one of the problem with my I/O and ISR.> > My ISR gets the interrupt source and queues it to a DPC routine. My DPC > routine will then raise a user Event with KeSetEvent(). The problem occurs > because of the DPC IRQ. It is too low and a critical section thread runs > over it.> > My ISR is called, gets a value queued for the DPC but another thread takes > over the processor with his KeSynchronizeExecution command and my DPC > routine only gets called 4-5 sec later. I know the KeSetEvent cannot be used > in the ISR. The DPC runs at DISPATCH_LEVEL but my critifical section > prevents it from executing as soon as my ISR is finished.> > I need to notify a user application with a user event before the critical > section takes over after the ISR. Is there any way to do this?> Frederick Guillemot> > Introducing the City @ Live! Take a tour!> http://getyourliveid.ca/?icid=LIVEIDENCA006 > > > > —> NTDEV is sponsored by OSR> > For our schedule of WDF, WDM, debugging and other seminars visit: > http://www.osr.com/seminars> > To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Discover new ways to stay in touch with Windows Live! Visit the City @ Live today!
http://getyourliveid.ca/?icid=LIVEIDENCA006

You at a mininum have to rewrite thing so that if the application is writing
something that needs to have an interrupt then block all other actions on
the card till the interupt occurs and DPC is fired. Basically, something
like grab a kernel mutex at the start of all operations, and if the
operation turns out to be an interrupt one do not release it at the dispatch
routine exit. Then in the DPC after setting the event release the mutex.

The problem here is your performance will suck. A better solution would be
to look at the whole design, and abstract this stuff to something that does
not have these hardware/software requirments.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

“Frederick Guillemot” wrote in message
news:xxxxx@ntdev…

Hello,

To answer your questions:
- The applications send I/O commands to the driver. I have limited the
amount of commands with a mutex to 1.
- Sometimes Interrupts on the card occur. They are used by the user
application to do processing and calculations (I have no clue at the
specific) but the interrupts need to be treated by the druver in a maximum
time of 1s. Some applications send a I/O control to write a byte at 0x5. The
card mechanism automaticly generates an interrupt and it caught by my ISR.

The problem occurs when we run our Testing software. Two threads are used.
Thread1 writes to 0x5 to generate Interrupt and waits for the UserEvent. It
calculates time…Thread2 will make a I/O to WriteByte continuasouly.

What happens is that Thread1 writes byte (so critical section occurs). ISR
runs and queues to DPC. Thread 2 gets control and does X WriteByte in a row
(critical sections here) before the DPC routine gets called. It results in a
> 1sec delay between the 0x5 Write byte and the Application notified.

The critical section used is:
====
void WriteByte(Addr, ByteToBeWritten)
{
- Write ModuleRoutingByte to Address (0x1D)
- Write ByteToBeWritten to Addr
}====

The ISR routine:
=====
void MyISR()
{
- ModuleRoutingByte = Read from Address 0x1D
- Read ModuleThatDidInterrupt
- Write ModuleThatDidInterrupt to Address 0x1D
- Remove Interrupt
- Write ModuleRoutingByte to Address (0x1D)

QueueToDpc(ModuleThatDidInterrupt)
}
=====

The DPC routine:
=====
void MyISR()
{
KeSetEvent(UserEvent);
}
=====
> From: xxxxx@acm.org> Subject: Re:[ntdev] KeSetEvent + ISR/DPC…> Date:
> Thu, 6 Dec 2007 15:24:54 -0500> To: xxxxx@lists.osr.com> > DPC always run
> at DISPATCH_LEVEL it is impossible for it to be TOO LOW, just > that you
> have designed things poorly. Why do you need to notify the > application,
> before someone else get at the device registers? You should be > saving
> all the information you need at interrupt time, then let the DPC do > what
> it wants.> > Give us a description of what the heck you are trying to do
> (not set an > event, but why the event is important, what the application
> is going to do, > what the critical section does, etc).> > > – > Don Burn
> (MVP, Windows DDK)> Windows 2k/XP/2k3 Filesystem and Driver Consulting>
> Website: http://www.windrvr.com> Blog: http://msmvps.com/blogs/WinDrvr>
> Remove StopSpam to reply> > > > “Frederick Guillemot”
> wrote in message > news:xxxxx@ntdev…> > Hello,>
> > I seem to have a problem with concurrent applications using my driver on
> a > Core Quad.> > To solve this issue, I used a critical section
> (KeSynchronizeExecution) to > access specific adress in my I/O. This
> raises the IRQ to my Interrupt IRQL > thus solving one of the problem with
> my I/O and ISR.> > My ISR gets the interrupt source and queues it to a DPC
> routine. My DPC > routine will then raise a user Event with KeSetEvent().
> The problem occurs > because of the DPC IRQ. It is too low and a critical
> section thread runs > over it.> > My ISR is called, gets a value queued
> for the DPC but another thread takes > over the processor with his
> KeSynchronizeExecution command and my DPC > routine only gets called 4-5
> sec later. I know the KeSetEvent cannot be used > in the ISR. The DPC runs
> at DISPATCH_LEVEL but my critifical section > prevents it from executing
> as soon as my ISR is finished.> > I need to notify a user application with
> a user event before the critical > section takes over after the ISR. Is
> there any way to do this?> Frederick Guillemot>
> >
> Introducing the City @ Live! Take a tour!>
> http://getyourliveid.ca/?icid=LIVEIDENCA006 > > > > —> NTDEV is
> sponsored by OSR> > For our schedule of WDF, WDM, debugging and other
> seminars visit: > http://www.osr.com/seminars> > To unsubscribe, visit the
> List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Discover new ways to stay in touch with Windows Live! Visit the City @ Live
today!
http://getyourliveid.ca/?icid=LIVEIDENCA006

> My ISR gets the interrupt source and queues it to a DPC routine. My DPC routine

will then raise a user Event with KeSetEvent(). The problem occurs because of
the DPC IRQ. It is too low and a critical section thread runs over it. My ISR is called,
gets a value queued for the DPC but another thread takes over the processor
with his KeSynchronizeExecution command and my DPC routine only gets called
4-5 sec later. I know the KeSetEvent cannot be used in the ISR. The DPC runs at DISPATCH_LEVEL but my critifical section prevents it from executing as soon as
my ISR is finished.

Just incredible piece of nonsense…

Context switch just cannot occur at elevated IRQL. Therefore, no other thread can take over the CPU your ISR runs on before your DPC gets executed, although some other thread that runs on another CPU may, indeed, call KeSynchronizeExecution(). If it happens, the CPU that calls KeSynchronizeExecution() will not respond to interrupts of any priority below your DIRQL before the original IRQL gets restored, and no CPU in the system will be able to execute your ISR until interrupt spinlock that protects your ISR gets released. In any case, this call has no effect of execution of DPCs that your ISR has queued while running on another CPU.

I am afraid you have to learn a bit of kernel-level basics before you can proceed - the above excerpt proves that you have no idea about kernel mechanics whatsoever…

Anton Bassov

Have you tried to insert a small delay in your Thread2 ? That will prevent it from monopolizing the critical section. You can even try to put the small delay in your driver, at the point you do the I/O access that generates the interrupt. A few milliseconds might be enough to give the OS a chance to context-switch your thread, and that may end up happening a lot sooner than your 1 second deadline.

Hope this helps!

Alberto.

----- Original Message -----
From: Frederick Guillemot
To: Windows System Software Devs Interest List
Sent: Thursday, December 06, 2007 3:52 PM
Subject: RE: [ntdev] KeSetEvent + ISR/DPC…

Hello,

To answer your questions:

  • The applications send I/O commands to the driver. I have limited the amount of commands with a mutex to 1.
  • Sometimes Interrupts on the card occur. They are used by the user application to do processing and calculations (I have no clue at the specific) but the interrupts need to be treated by the druver in a maximum time of 1s. Some applications send a I/O control to write a byte at 0x5. The card mechanism automaticly generates an interrupt and it caught by my ISR.

The problem occurs when we run our Testing software. Two threads are used. Thread1 writes to 0x5 to generate Interrupt and waits for the UserEvent. It calculates time…Thread2 will make a I/O to WriteByte continuasouly.

What happens is that Thread1 writes byte (so critical section occurs). ISR runs and queues to DPC. Thread 2 gets control and does X WriteByte in a row (critical sections here) before the DPC routine gets called. It results in a > 1sec delay between the 0x5 Write byte and the Application notified.

The critical section used is:

void WriteByte(Addr, ByteToBeWritten)
{

  • Write ModuleRoutingByte to Address (0x1D)
  • Write ByteToBeWritten to Addr
    }
    ====

The ISR routine:

void MyISR()
{

  • ModuleRoutingByte = Read from Address 0x1D
  • Read ModuleThatDidInterrupt
  • Write ModuleThatDidInterrupt to Address 0x1D
  • Remove Interrupt
  • Write ModuleRoutingByte to Address (0x1D)

QueueToDpc(ModuleThatDidInterrupt)
}

=====

The DPC routine:

void MyISR()
{
KeSetEvent(UserEvent);
}

=====

From: xxxxx@acm.org
> Subject: Re:[ntdev] KeSetEvent + ISR/DPC…
> Date: Thu, 6 Dec 2007 15:24:54 -0500
> To: xxxxx@lists.osr.com
>
> DPC always run at DISPATCH_LEVEL it is impossible for it to be TOO LOW, just
> that you have designed things poorly. Why do you need to notify the
> application, before someone else get at the device registers? You should be
> saving all the information you need at interrupt time, then let the DPC do
> what it wants.
>
> Give us a description of what the heck you are trying to do (not set an
> event, but why the event is important, what the application is going to do,
> what the critical section does, etc).
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> Website: http://www.windrvr.com
> Blog: http://msmvps.com/blogs/WinDrvr
> Remove StopSpam to reply
>
>
>
> “Frederick Guillemot” wrote in message
> news:xxxxx@ntdev…
>
> Hello,
>
> I seem to have a problem with concurrent applications using my driver on a
> Core Quad.
>
> To solve this issue, I used a critical section (KeSynchronizeExecution) to
> access specific adress in my I/O. This raises the IRQ to my Interrupt IRQL
> thus solving one of the problem with my I/O and ISR.
>
> My ISR gets the interrupt source and queues it to a DPC routine. My DPC
> routine will then raise a user Event with KeSetEvent(). The problem occurs
> because of the DPC IRQ. It is too low and a critical section thread runs
> over it.
>
> My ISR is called, gets a value queued for the DPC but another thread takes
> over the processor with his KeSynchronizeExecution command and my DPC
> routine only gets called 4-5 sec later. I know the KeSetEvent cannot be used
> in the ISR. The DPC runs at DISPATCH_LEVEL but my critifical section
> prevents it from executing as soon as my ISR is finished.
>
> I need to notify a user application with a user event before the critical
> section takes over after the ISR. Is there any way to do this?
> Frederick Guillemot
> _________________________________________________________________
> Introducing the City @ Live! Take a tour!
> http://getyourliveid.ca/?icid=LIVEIDENCA006
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

------------------------------------------------------------------------------
Books, DVD’s, gadgets, music and more. Shop online with Sympatico / MSN Shopping today!

NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer