Handing kernel interrupts in application

I was advised here to use the inverted call pattern to handle kerenl interrupts in my application.

Doron Holan wrote the following:
The best solution is to create a manual WDFQUEUE. Put the special ?an interrupt? happened IOCTL request into that queue. When the DPC for ISR runs, remove the first request from the manual queue and complete. The app will know the interrupt occurred b/c the i/o request completed. You can even put data into an output buffer if you want. This pattern is called an ?inverted call?. You can research that term on osr?s site or the archives for this list.

The problem is that if windows does somethnig in background (e.g maxmizing a window, launching another appilcation, the application will not send the IOCTL request to the driver. If an interrupt occurs at this period, the manual queue will be empty. no request will be completed. The interrupt will be lost and the application will miss it.

In such a case the DPC can set an event. The IOCTL request will first check the status of this event. If it is set, the application will know an interrupt occured and complete the request.

Is this the optimal solution ?

Thanks.

Forget about using events. What you propose will record that one DPC was missed. What if there are 2 missed? Also, are you using any kind of synchronization between checking the state of the event and setting/clearing it? If not, the set/check state can race with each other, still leading to a missed notification. Read my other response on how to fix this properly

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@elta.co.il
Sent: Wednesday, December 17, 2008 8:42 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Handing kernel interrupts in application

I was advised here to use the inverted call pattern to handle kerenl interrupts in my application.

Doron Holan wrote the following:
The best solution is to create a manual WDFQUEUE. Put the special ?an interrupt? happened IOCTL request into that queue. When the DPC for ISR runs, remove the first request from the manual queue and complete. The app will know the interrupt occurred b/c the i/o request completed. You can even put data into an output buffer if you want. This pattern is called an ?inverted call?. You can research that term on osr?s site or the archives for this list.

The problem is that if windows does somethnig in background (e.g maxmizing a window, launching another appilcation, the application will not send the IOCTL request to the driver. If an interrupt occurs at this period, the manual queue will be empty. no request will be completed. The interrupt will be lost and the application will miss it.

In such a case the DPC can set an event. The IOCTL request will first check the status of this event. If it is set, the application will know an interrupt occured and complete the request.

Is this the optimal solution ?

Thanks.


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

Another approach would be to build a Q of items (you define the struct).
In your DPCforIsr routine grab a pre-allocated item, fill it with
relevent information and put it on a Q. In the ioctl handler, pull the
item off the Q or if nothing in Q, return nothing. Offcourse your app
needs to be able handle the situation if there is no item in the Q.

Harish

-----Original Message-----
From: xxxxx@elta.co.il [mailto:xxxxx@elta.co.il]
Sent: Wednesday, December 17, 2008 8:42 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Handing kernel interrupts in application

I was advised here to use the inverted call pattern to handle kerenl
interrupts in my application.

Doron Holan wrote the following:
The best solution is to create a manual WDFQUEUE. Put the special ?an
interrupt? happened IOCTL request into that queue. When the DPC for ISR
runs, remove the first request from the manual queue and complete. The
app will know the interrupt occurred b/c the i/o request completed. You
can even put data into an output buffer if you want. This pattern is
called an ?inverted call?. You can research that term on osr?s site or
the archives for this list.

The problem is that if windows does somethnig in background (e.g
maxmizing a window, launching another appilcation, the application will
not send the IOCTL request to the driver. If an interrupt occurs at this
period, the manual queue will be empty. no request will be completed.
The interrupt will be lost and the application will miss it.

In such a case the DPC can set an event. The IOCTL request will first
check the status of this event. If it is set, the application will know
an interrupt occured and complete the request.

Is this the optimal solution ?

Thanks.


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

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@elta.co.il
Sent: Wednesday, December 17, 2008 11:42 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Handing kernel interrupts in application

I was advised here to use the inverted call pattern to handle kerenl
interrupts in my application.

Doron Holan wrote the following:
The best solution is to create a manual WDFQUEUE. Put the special ?an
interrupt? happened IOCTL request into that queue. When the DPC for ISR
runs, remove the first request from the manual queue and complete. The app
will know the interrupt occurred b/c the i/o request completed. You can
even put data into an output buffer if you want. This pattern is called an
?inverted call?. You can research that term on osr?s site or the archives
for this list.

The problem is that if windows does somethnig in background (e.g maxmizing a
window, launching another appilcation, the application will not send the
IOCTL request to the driver.
************************************
*
So? This is based on the premise there is only one of them there in the
first place. If you want to handle this case, you have to submit several of
them.

Many realtime programmers think that they should notify the app on every
interrupt. I’m not sure I understand this logic, and it sounds more like an
attempt to warp Windows into following some inappropriate device model
instead of working with the device model that exists.
*
************************************

If an interrupt occurs at this period, the manual queue will be empty. no
request will be completed. The interrupt will be lost and the application
will miss it.
************************************
*
The queue is empty only because you didn’t put enough things into it. The
resizing, moving, etc. issues are a tiny, tiny, tiny part of the problem.
If you want to capture something as frequent as interrupts, you will need to
have LOTS of pending IRPs. When I had a situation like this, I had to queue
up 50 of them to make sure we didn’t lose data (complicated problem and it
wasn’t interrupts, but NDA creeps in here…)
*
************************************

In such a case the DPC can set an event. The IOCTL request will first check
the status of this event. If it is set, the application will know an
interrupt occured and complete the request.
************************************
*
This solves nothing. It sets an event. Whoopee. And if the application
doesn’t see the completion in time, the next interrupt does a second
SetEvent, and the fact that an interrupt occurred is lost again. Give up on
the idea that the application will respond in a predictable, bounded time,
it isn’t going to happen. Assume that you will have to queue many such
requests up to keep up the rate, and even then, it only works in bursty
conditions.
*
************************************
Is this the optimal solution ?
************************************
*
As I indicated, it isn’t even a solution, forget “optimal”.
*
************************************
Thanks.


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


This message has been scanned for viruses and dangerous content by
MailScanner, and is believed to be clean.

> The queue is empty only because you didn’t put enough things into it. The resizing, moving, etc.

issues are a tiny, tiny, tiny part of the problem.

Actually, the poster is not that far away from the truth, although, certainly, he presented the idea the wrong way - this is not the question of “background task” but simply of impossibility to predict exact time the thread that submits requests gets rescheduled. Consider the scenario when driver completes all outstanding requests, but new ones are not getting submitted because the thread that submits them just cannot get to the CPU. Certainly, you can make the queue of requests pretty large, but, again, it depends on interrupt frequency and the system load - the heavier the system load is, the higher the probability of the above mentioned scenario is. For example, just consider NIC interrupt on a server system - you don’t know in advance how heavy the system load is, and you don’t know interrupt frequency because you don’t know how heavy the network traffic is. Therefore, calculating the queue size in advance is not the easiest task one would imagine…

Anton Bassov

I agree. The problem is that the OP makes the assumption that completing an
IRP necessarily results in instantaneous dispatching of the waiting thread,
which I find to be a common misunderstanding about operating systems. The
similar assumption is that the generating thread is always available. In
the non-realtime world, there is no reason to have these expectations. So
you compensate for the thread delays (producer or consumer) by use of large
buffers.

What I find odd is that an application program should care in the slighest
about interrupts. This should be an irrelevant implementation detail that a
driver conceals, rather than makes a fundamental primitive.

Queuing theory says that you can NEVER calculate the queue size in advance
under the scenario you suggest, which is, unfortunately, the reality of what
we are working in. How did I determine I needed 50 IRPs to handle the
situation I had? Because 40 caused data loss. Maybe, under a different set
of conditions, it should be 100 (which is why it is handled as a
user-configurable parameter in the application). [Question: if the average
service time == the average interarrival time, what is the maximum queue
size required?]
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Wednesday, December 17, 2008 5:43 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Handing kernel interrupts in application

The queue is empty only because you didn’t put enough things into it. The
resizing, moving, etc.
issues are a tiny, tiny, tiny part of the problem.

Actually, the poster is not that far away from the truth, although,
certainly, he presented the idea the wrong way - this is not the question of
“background task” but simply of impossibility to predict exact time the
thread that submits requests gets rescheduled. Consider the scenario when
driver completes all outstanding requests, but new ones are not getting
submitted because the thread that submits them just cannot get to the CPU.
Certainly, you can make the queue of requests pretty large, but, again, it
depends on interrupt frequency and the system load - the heavier the system
load is, the higher the probability of the above mentioned scenario is. For
example, just consider NIC interrupt on a server system - you don’t know in
advance how heavy the system load is, and you don’t know interrupt frequency
because you don’t know how heavy the network traffic is. Therefore,
calculating the queue size in advance is not the easiest task one would
imagine…

Anton Bassov


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


This message has been scanned for viruses and dangerous content by
MailScanner, and is believed to be clean.

The answer to your question is infinite.

Well, as if I’ve to sign something !
Prokash Sinha
http://prokash.squarespace.com
Success has many fathers, but failure is an orphan.

----- Original Message -----
From: “Joseph M. Newcomer”
To: “Windows System Software Devs Interest List”
Sent: Wednesday, December 17, 2008 4:53 PM
Subject: RE: [ntdev] Handing kernel interrupts in application

>I agree. The problem is that the OP makes the assumption that completing
>an
> IRP necessarily results in instantaneous dispatching of the waiting
> thread,
> which I find to be a common misunderstanding about operating systems. The
> similar assumption is that the generating thread is always available. In
> the non-realtime world, there is no reason to have these expectations. So
> you compensate for the thread delays (producer or consumer) by use of
> large
> buffers.
>
> What I find odd is that an application program should care in the slighest
> about interrupts. This should be an irrelevant implementation detail that
> a
> driver conceals, rather than makes a fundamental primitive.
>
> Queuing theory says that you can NEVER calculate the queue size in advance
> under the scenario you suggest, which is, unfortunately, the reality of
> what
> we are working in. How did I determine I needed 50 IRPs to handle the
> situation I had? Because 40 caused data loss. Maybe, under a different
> set
> of conditions, it should be 100 (which is why it is handled as a
> user-configurable parameter in the application). [Question: if the
> average
> service time == the average interarrival time, what is the maximum queue
> size required?]
> joe
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of
> xxxxx@hotmail.com
> Sent: Wednesday, December 17, 2008 5:43 PM
> To: Windows System Software Devs Interest List
> Subject: RE:[ntdev] Handing kernel interrupts in application
>
>> The queue is empty only because you didn’t put enough things into it. The
> resizing, moving, etc.
>> issues are a tiny, tiny, tiny part of the problem.
>
> Actually, the poster is not that far away from the truth, although,
> certainly, he presented the idea the wrong way - this is not the question
> of
> “background task” but simply of impossibility to predict exact time the
> thread that submits requests gets rescheduled. Consider the scenario when
> driver completes all outstanding requests, but new ones are not getting
> submitted because the thread that submits them just cannot get to the CPU.
> Certainly, you can make the queue of requests pretty large, but, again, it
> depends on interrupt frequency and the system load - the heavier the
> system
> load is, the higher the probability of the above mentioned scenario is.
> For
> example, just consider NIC interrupt on a server system - you don’t know
> in
> advance how heavy the system load is, and you don’t know interrupt
> frequency
> because you don’t know how heavy the network traffic is. Therefore,
> calculating the queue size in advance is not the easiest task one would
> imagine…
>
>
> Anton Bassov
>
>
>
>
> —
> 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
>
> –
> This message has been scanned for viruses and dangerous content by
> MailScanner, and is believed to be clean.
>
>
> —
> 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

> In such a case the DPC can set an event. The IOCTL request will first check the status of this event.

I would use adding a node to a list instead of event.

The IOCTL looks at the list, if there are nodes - it consumes the oldest node from the list and returns its data content to the caller.

If the list is empty - then the IOCTL is pended and used as inverted call.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> I was advised here to use the inverted call pattern to handle kerenl interrupts in my application.

Well, what else would one expect from a “good adviser” on this list (IIRC, in this particular case it was Doron who suggested “inverted call”)??? After all, this is very typical for this list - once inverted call is supposed to be “better” than using events, everyone here would say “use inverted call” without even thinking about the problem in question, despite the fact that using events may be much more appropriate in a given situation.

IMHO, in situations like that inverted call is simply unreasonable for the reasons we have discussed here, i.e. you cannot calculate the queue size in advance. Look at your original solution presented on another thread

[begin quote]

  1. The WDF driver handles the interrupt in the ISR and sends a requesr to IsrDPC.

  2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

  3. The application sends an IOCTL code to check if an interrupt occured.

  4. The IOCTL handler calls:

4.1 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);

4.2 KeClearEvent (&Event)

4.3 WdfRequestComplete(Request, 0);

Is this the optimal mechanism ?

[end quote]

IMHO, in actuality steps 1 to 3 , indeed, describe an optimal solution that looks pretty much like fctl() - select() -read() sequence on UNIX. Such solution eliminates the problem that we are speaking about here. The only thing that needs modification is step 4. What you need here is a custom queue protected by a spinlock, and UM event ( I would rather use synchronization, rather than notification, event , so that it gets automatically reset when UM WaitForSingleObject() returns control).

UM application submits event handle with IOCTL ABC and then gets into the following infinite loop:

while(1)

{

WaitForSingleObject(…);

DeviceIoControl (IOCTL XYZ,…);

… process retrieved data

}

DPC inserts an element describing a given occurrence of interrupt into a queue and signals the event. As a result, the waiting thread gets unblocked and sends an IOCTL XYZ to a driver ( METHOD_BUFFERED is, of course , the most appropriate IO method here) . IOCTL handler copies all data from the queue to a system buffer, and frees queue elements. Access to the queue is synchronized with a spinlock, so that DPC and IOCTL handler don’t get into the race conditions with one another. Pure and simple - no problem either with a queue size or synchronization…

Anton Bassov

> 2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

No. IsrDPC allocates a node, fills it and attaches to the list.

This would be much better.

KeWaitForSingleObject in dispatch routine is a bad taste. Pend the IRP instead.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>> 2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

No. IsrDPC allocates a node, fills it and attaches to the list.

Well, if it simply attaches a node to the list without either setting an event or completing an outstanding request, how on Earth would it inform an app about the event then??? Concerning the latter option,
its drawbacks in a given situation seem to be self-evident (although, apparently, not to you - more on it below)

Pend the IRP instead.

Did you actually read this thread or you are saying “Pend the IRP” simply because you are unable to say anything “unapproved”, even when “approved” method is far from being optimal in a given situation???

Anton Bassov

> Well, if it simply attaches a node to the list without either setting an event or completing an

outstanding request,

Yes, surely the request must be filled and completed (without creating a new node) if there is such a request.

Did you actually read this thread or you are saying “Pend the IRP” simply because you are unable to

Events for KM/UM are worse then inverted calls in everything. They provide no advantages at all.

The whole thread of this is about “and what will we do if we will not be able to submit IRPs faster then the events occur in kmode?”. The 100% fine answer is - “then the kmode code allocates nodes and attaches them to the list, for later consumption by the IRPs”.

The total size of all nodes is only limited by the kernel memory which is huge. So, with this, you can relax about having this many pending IRPs - no data will be lost anyway, in the worst case you will have a small hit on memcpy() from node to the IRP.

More so, if the event generation protocol allows backpressure, the semantics like “please stall for a while, you’re too fast” - then backpressure can be applied when the node queue reaches some size.

TCP sockets in Windows work exactly this.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

I don’t see the advantage of a separate event over taking advantage of normal I/O completion logic. All that you gain is an additional kernel/user transition to fetch the data once you have been notified that it is available, whereas a pended IOCTL would both notify you and return data at the same time.

? S

-----Original Message-----
From: xxxxx@hotmail.com
Sent: Thursday, December 18, 2008 22:00
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Handing kernel interrupts in application

> I was advised here to use the inverted call pattern to handle kerenl interrupts in my application.

Well, what else would one expect from a “good adviser” on this list (IIRC, in this particular case it was Doron who suggested “inverted call”)??? After all, this is very typical for this list - once inverted call is supposed to be “better” than using events, everyone here would say “use inverted call” without even thinking about the problem in question, despite the fact that using events may be much more appropriate in a given situation.

IMHO, in situations like that inverted call is simply unreasonable for the reasons we have discussed here, i.e. you cannot calculate the queue size in advance. Look at your original solution presented on another thread

[begin quote]

1. The WDF driver handles the interrupt in the ISR and sends a requesr to IsrDPC.

2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

3. The application sends an IOCTL code to check if an interrupt occured.

4. The IOCTL handler calls:

4.1 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);

4.2 KeClearEvent (&Event)

4.3 WdfRequestComplete(Request, 0);

Is this the optimal mechanism ?

[end quote]

IMHO, in actuality steps 1 to 3 , indeed, describe an optimal solution that looks pretty much like fctl() - select() -read() sequence on UNIX. Such solution eliminates the problem that we are speaking about here. The only thing that needs modification is step 4. What you need here is a custom queue protected by a spinlock, and UM event ( I would rather use synchronization, rather than notification, event , so that it gets automatically reset when UM WaitForSingleObject() returns control).

UM application submits event handle with IOCTL ABC and then gets into the following infinite loop:

while(1)

{

WaitForSingleObject(…);

DeviceIoControl (IOCTL XYZ,…);

… process retrieved data

}

DPC inserts an element describing a given occurrence of interrupt into a queue and signals the event. As a result, the waiting thread gets unblocked and sends an IOCTL XYZ to a driver ( METHOD_BUFFERED is, of course , the most appropriate IO method here) . IOCTL handler copies all data from the queue to a system buffer, and frees queue elements. Access to the queue is synchronized with a spinlock, so that DPC and IOCTL handler don’t get into the race conditions with one another. Pure and simple - no problem either with a queue size or synchronization…

Anton Bassov


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

The advantage is that Anton has not participated in the long history of this
discussion, and so feels free to pronounce the consensus opinion wrong while
proceeding to rehash one of the many failed arguments to prove it wrong.

Mark Roddy

On Fri, Dec 19, 2008 at 9:22 AM, Skywing wrote:

> I don’t see the advantage of a separate event over taking advantage of
> normal I/O completion logic. All that you gain is an additional kernel/user
> transition to fetch the data once you have been notified that it is
> available, whereas a pended IOCTL would both notify you and return data at
> the same time.
>
> ? S
>
> -----Original Message-----
> From: xxxxx@hotmail.com
> Sent: Thursday, December 18, 2008 22:00
> To: Windows System Software Devs Interest List
> Subject: RE:[ntdev] Handing kernel interrupts in application
>
>
> > I was advised here to use the inverted call pattern to handle kerenl
> interrupts in my application.
>
> Well, what else would one expect from a “good adviser” on this list
> (IIRC, in this particular case it was Doron who suggested “inverted
> call”)??? After all, this is very typical for this list - once inverted
> call is supposed to be “better” than using events, everyone here would say
> “use inverted call” without even thinking about the problem in question,
> despite the fact that using events may be much more appropriate in a given
> situation.
>
> IMHO, in situations like that inverted call is simply unreasonable for
> the reasons we have discussed here, i.e. you cannot calculate the queue size
> in advance. Look at your original solution presented on another thread
>
> [begin quote]
>
> 1. The WDF driver handles the interrupt in the ISR and sends a requesr to
> IsrDPC.
>
> 2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);
>
> 3. The application sends an IOCTL code to check if an interrupt occured.
>
> 4. The IOCTL handler calls:
>
> 4.1 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
>
> 4.2 KeClearEvent (&Event)
>
> 4.3 WdfRequestComplete(Request, 0);
>
> Is this the optimal mechanism ?
>
> [end quote]
>
> IMHO, in actuality steps 1 to 3 , indeed, describe an optimal solution that
> looks pretty much like fctl() - select() -read() sequence on UNIX. Such
> solution eliminates the problem that we are speaking about here. The only
> thing that needs modification is step 4. What you need here is a custom
> queue protected by a spinlock, and UM event ( I would rather use
> synchronization, rather than notification, event , so that it gets
> automatically reset when UM WaitForSingleObject() returns control).
>
>
> UM application submits event handle with IOCTL ABC and then gets into the
> following infinite loop:
>
>
> while(1)
>
> {
>
> WaitForSingleObject(…);
>
> DeviceIoControl (IOCTL XYZ,…);
>
> … process retrieved data
>
>
> }
>
> DPC inserts an element describing a given occurrence of interrupt into a
> queue and signals the event. As a result, the waiting thread gets unblocked
> and sends an IOCTL XYZ to a driver ( METHOD_BUFFERED is, of course , the
> most appropriate IO method here) . IOCTL handler copies all data from the
> queue to a system buffer, and frees queue elements. Access to the queue is
> synchronized with a spinlock, so that DPC and IOCTL handler don’t get into
> the race conditions with one another. Pure and simple - no problem either
> with a queue size or synchronization…
>
>
> Anton Bassov
>
> —
> 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
>
> —
> 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
>

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Friday, December 19, 2008 1:01 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Handing kernel interrupts in application

I was advised here to use the inverted call pattern to handle kerenl
interrupts in my application.

Well, what else would one expect from a “good adviser” on this list (IIRC,
in this particular case it was Doron who suggested “inverted call”)???
After all, this is very typical for this list - once inverted call is
supposed to be “better” than using events, everyone here would say “use
inverted call” without even thinking about the problem in question, despite
the fact that using events may be much more appropriate in a given
situation.

IMHO, in situations like that inverted call is simply unreasonable for the
reasons we have discussed here, i.e. you cannot calculate the queue size in
advance. Look at your original solution presented on another thread

[begin quote]

  1. The WDF driver handles the interrupt in the ISR and sends a requesr to
    IsrDPC.

  2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

  3. The application sends an IOCTL code to check if an interrupt occured.

  4. The IOCTL handler calls:

4.1 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
****
*
4.1.5: The driver handles an interrupt and does a KeSetEvent
*
****

4.2 KeClearEvent (&Event)

4.3 WdfRequestComplete(Request, 0);

Is this the optimal mechanism ?

[end quote]

IMHO, in actuality steps 1 to 3 , indeed, describe an optimal solution that
looks pretty much like fctl() - select() -read() sequence on UNIX. Such
solution eliminates the problem that we are speaking about here. The only
thing that needs modification is step 4. What you need here is a custom
queue protected by a spinlock, and UM event ( I would rather use
synchronization, rather than notification, event , so that it gets
automatically reset when UM WaitForSingleObject() returns control).

UM application submits event handle with IOCTL ABC and then gets into the
following infinite loop:

while(1)

{

WaitForSingleObject(…);

DeviceIoControl (IOCTL XYZ,…);

… process retrieved data

}

DPC inserts an element describing a given occurrence of interrupt into a
queue and signals the event. As a result, the waiting thread gets unblocked
and sends an IOCTL XYZ to a driver ( METHOD_BUFFERED is, of course , the
most appropriate IO method here) . IOCTL handler copies all data from the
queue to a system buffer, and frees queue elements. Access to the queue is
synchronized with a spinlock, so that DPC and IOCTL handler don’t get into
the race conditions with one another. Pure and simple - no problem either
with a queue size or synchronization…

Anton Bassov


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


This message has been scanned for viruses and dangerous content by
MailScanner, and is believed to be clean.

This notify-on-interrupt-and-fetch-data-later paradigm is common in embedded
systems, and this is just an attempt to make Windows work like one of these
embedded systems. The schema below is fundamentally buggy, and illustrates
the kind of erroneous thinking that usually goes with this model when
someone tries to force it into real operating systems. For example, using
an event instead of a semaphore. The point is that the interrupts are
free-running, according to what we’ve been told, so there is a fundamental
race condition.

Whenever anyone proposes an asynchronous solution involving events, the
first thing to do is look for the fundamental race condition that
invalidates the solution, and it is glaringly obvious in the code below;
I’ve already posted it.
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Skywing
Sent: Friday, December 19, 2008 9:22 AM
To: Windows System Software Devs Interest List
Subject: RE: RE:[ntdev] Handing kernel interrupts in application

I don’t see the advantage of a separate event over taking advantage of
normal I/O completion logic. All that you gain is an additional kernel/user
transition to fetch the data once you have been notified that it is
available, whereas a pended IOCTL would both notify you and return data at
the same time.

  • S

-----Original Message-----
From: xxxxx@hotmail.com
Sent: Thursday, December 18, 2008 22:00
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Handing kernel interrupts in application

> I was advised here to use the inverted call pattern to handle kerenl
interrupts in my application.

Well, what else would one expect from a “good adviser” on this list (IIRC,
in this particular case it was Doron who suggested “inverted call”)???
After all, this is very typical for this list - once inverted call is
supposed to be “better” than using events, everyone here would say “use
inverted call” without even thinking about the problem in question, despite
the fact that using events may be much more appropriate in a given
situation.

IMHO, in situations like that inverted call is simply unreasonable for the
reasons we have discussed here, i.e. you cannot calculate the queue size in
advance. Look at your original solution presented on another thread

[begin quote]

1. The WDF driver handles the interrupt in the ISR and sends a requesr to
IsrDPC.

2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

3. The application sends an IOCTL code to check if an interrupt occured.

4. The IOCTL handler calls:

4.1 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);

4.2 KeClearEvent (&Event)

4.3 WdfRequestComplete(Request, 0);

Is this the optimal mechanism ?

[end quote]

IMHO, in actuality steps 1 to 3 , indeed, describe an optimal solution that
looks pretty much like fctl() - select() -read() sequence on UNIX. Such
solution eliminates the problem that we are speaking about here. The only
thing that needs modification is step 4. What you need here is a custom
queue protected by a spinlock, and UM event ( I would rather use
synchronization, rather than notification, event , so that it gets
automatically reset when UM WaitForSingleObject() returns control).

UM application submits event handle with IOCTL ABC and then gets into the
following infinite loop:

while(1)

{

WaitForSingleObject(…);

DeviceIoControl (IOCTL XYZ,…);

… process retrieved data

}

DPC inserts an element describing a given occurrence of interrupt into a
queue and signals the event. As a result, the waiting thread gets unblocked
and sends an IOCTL XYZ to a driver ( METHOD_BUFFERED is, of course , the
most appropriate IO method here) . IOCTL handler copies all data from the
queue to a system buffer, and frees queue elements. Access to the queue is
synchronized with a spinlock, so that DPC and IOCTL handler don’t get into
the race conditions with one another. Pure and simple - no problem either
with a queue size or synchronization…

Anton Bassov


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


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


This message has been scanned for viruses and dangerous content by
MailScanner, and is believed to be clean.

See below…

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Friday, December 19, 2008 9:06 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Handing kernel interrupts in application

> 2. IsrDPC calls KeSetEvent (&Event, IO_NO_INCREMENT, FALSE);

No. IsrDPC allocates a node, fills it and attaches to the list.

Well, if it simply attaches a node to the list without either setting an
event or completing an outstanding request, how on Earth would it inform an
app about the event then??? Concerning the latter option, its drawbacks in a
given situation seem to be self-evident (although, apparently, not to you -
more on it below)
**********
*
This is the failure in thinking. That list is handled as a standard queue.
If there is a pending IOCTL and the queue is empty, you complete the request
with the data; if there is no pending IOCTL, you pend it.

Why should it “notify” the app at all? Either the app has a pending
DeviceIoControl, in which case, it receives a “notification”, or it doesn’t,
in which case it cannot receive a notification. Moving this model to the
UM/KM Event model (note: events are ALWAYS wrong in this context; semaphores
are the only type that makes sense!), if the thread is busy, it isn’t going
to receive any “notification” anyway, and the cost of the WFSO is going to
be roughly that of DeviceIoControl (kernel transition cost would be the
dominant cost).

This whole model that the app requires “notification” is the failure here.
Apps do not CARE about notifications that data is available, they only care
about data itself. Making it a two-step process instead of one-step process
makes no sense.

I’ve said this several times: the app and the driver are not coroutines in
an embedded system, so why try to make them so?
*
**********

Pend the IRP instead.

Did you actually read this thread or you are saying “Pend the IRP” simply
because you are unable to say anything “unapproved”, even when “approved”
method is far from being optimal in a given situation???
**********
*
If your criterion of “optimal” is “it is done my way” then yes, it is far
from optimal. But on the other hand, it DOES work, and works well, and
works within the Windows I/O model, and it doesn’t have some weird idea that
apps care about notification of data being present. Apps NEVER care about
such notifications; as I said, they only care about the data.

Here’s the real criterion for success: write the user interface specs FIRST.
If they are too hard to explain, the design is probably wrong. Something
that involves waiting for interrupts and THEN retrieving the data
(especially with the fundamental race condition already demonstrated, that
renders the code completely erroneous) is not a reasonable model for the
application programmer.
*
**********
Anton Bassov


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


This message has been scanned for viruses and dangerous content by
MailScanner, and is believed to be clean.

Ken and Mark,

I don’t see the advantage of a separate event over taking advantage of normal I/O completion logic

The advantage is that Anton has not participated in the long history of this discussion, and so feels
free to pronounce the consensus opinion wrong

I am afraid you got me wrong , guys - I am not saying is that events are better than inverted calls, because both techniques have their advantage in any given situation. However, I do object to using this or that technique under any circumstances, no matter what and no matter how, and, unfortunately, this happens to be the case with the inverted call. In fact, Mark’s statement makes me laugh, because
an abstract “event vs inverted call” discussion without mentioning a particular scenario just does not seem to make sense in itself, so I just wonder how someone could reach a consensus in a meaningless discussion …

Inverted call is good when frequency of notifications is more or less predictable, and the total amounts of processed data are reasonably low. However, if events may come at unpredictable time, unpredictable frequency and involve unpredictable amounts of data, problems may arise. If you make your IRP pool a way too big, i.e. IRPs are submitted at a higher rate than completed, you risk running out of non-paged memory, because IRP buffer is non-pageable. If it is too small, you will start missing events, i.e. something the OP is concerned about here. In situation like that, unless you are just desperate to write
fairly complex code that relies upon statistical analysis, use of events seem to be much better option.

No, I DEFINITELY don’t say that events are generally better than inverted calls . For example, unless we are speaking about megs of data per second, using events for synchronizing an access to the shared buffer is generally a bad idea - it immediately destroys any potential advantage that one expect to gain by sharing a buffer, in the first place. Therefore, it is better to use inverted call here. However, using events for notifying an app about driver events that may come at unpredictable time, unpredictable frequency and involve unpredictable amounts of data may be better than relying upon the inverted call

Anton Bassov

wrote in message news:xxxxx@ntdev…
>
> Inverted call is good when frequency of notifications is more or less
> predictable, and the total amounts of processed data are reasonably low.
> However, if events may come at unpredictable time, unpredictable frequency
> and involve unpredictable amounts of data, problems may arise. If you make
> your IRP pool a way too big, i.e. IRPs are submitted at a higher rate
> than completed, you risk running out of non-paged memory, because IRP
> buffer is non-pageable. If it is too small, you will start missing events,
> i.e. something the OP is concerned about here. In situation like that,
> unless you are just desperate to write
> fairly complex code that relies upon statistical analysis, use of events
> seem to be much better option.
>
But many of the same problems arise with events. In any case where you
have high bandwidth response situations you can loose data or events. If
you do not catch the event, or have fairly complex model to handle N events
you still have problems. So for many situations the tradeoffs do not
change, except that events require some detection of consumer failure.
Even though I normally consider events dubious, there are uses for them and
shared memory, but they are a lot less frequent than most people believe.


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

> This is the failure in thinking. That list is handled as a standard queue.

If there is a pending IOCTL and the queue is empty, you complete the request with the data;
if there is no pending IOCTL, you pend it.

Indeed, there is a failure in thinking, but not in mine - how can you pend non-existing IOCTL??? Please don’t forget that we are speaking about the situation when requests are pended by IOCTL handler and completed by DPC. Therefore, the maximum that can be done by DPC here when no outstanding IRP is available is queuing data. As long as there is some outstanding data, IRP will get completed, rather than pended, by a handler - it will get pended only if there is no data available, and, in such case, it will get completed by DPC when data becomes available…

Why should it “notify” the app at all?

I just made an assumption that you don’t want to implement fairly complex algorithms
of statistical analysis when data arrives unpredictable time, unpredictable frequency and is of unpredictable amounts so that you can adjust the size of a queue of outstanding IRPs dynamically, and, instead, choose a simple solution of informing an app and making it retrieve data

Anton Bassov