best way to kill a FileRead()?

Hello all,

I am working with an SDIO-based device; an application using it is
supposed to block in a ReadFile() until a message is available from the
device. The device generates an interrupt when a message is available.
The application spends a long time waiting for ReadFile() to return, and
chances are that the user will kill the application. What do I need to
do to gracefully handle aborting the read request?

The current implementation is as follows: the interrupt service callback
sets an event flag using KeSetEvent(). The queue’s EvtIoRead calls
KeWaitForSingleObject() on this flag thus blocking, and only performs
the actual read after the event flag is set by the interrupt service
callback.

I set Alertable parameter to TRUE in the KeWaitForSingleObject(), and
this seems to make the WaitForSingleObject() exit so that I could
complete EvtIoRead(). Without this, the thread never died and I had to
cycle power on the machine. Is this all that is needed? Or, do I need
to mark the request as cancellable and implement a cancellation
callback?

Thanks
Rachel

You don’t want an altertable wait. You pretty much never want to infinitely block your dispatching function. Instead, forward the read to manual queue. When the interrupt/message occurs, in your DPC pull the request out the manual queue and complete it. Putting it into the manual queue will make the request cancelable.

d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Michelson Rachel-CRK007
Sent: Thursday, January 05, 2012 3:13 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] best way to kill a FileRead()?

Hello all,

I am working with an SDIO-based device; an application using it is supposed to block in a ReadFile() until a message is available from the device. The device generates an interrupt when a message is available.
The application spends a long time waiting for ReadFile() to return, and chances are that the user will kill the application. What do I need to do to gracefully handle aborting the read request?

The current implementation is as follows: the interrupt service callback sets an event flag using KeSetEvent(). The queue’s EvtIoRead calls
KeWaitForSingleObject() on this flag thus blocking, and only performs the actual read after the event flag is set by the interrupt service callback.

I set Alertable parameter to TRUE in the KeWaitForSingleObject(), and this seems to make the WaitForSingleObject() exit so that I could complete EvtIoRead(). Without this, the thread never died and I had to cycle power on the machine. Is this all that is needed? Or, do I need to mark the request as cancellable and implement a cancellation callback?

Thanks
Rachel


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

> You don’t want an altertable wait. You pretty much never want to

infinitely block your dispatching function. Instead, forward the read to
manual queue. When the interrupt/message occurs, in your DPC pull the
request out the manual queue and complete it. Putting it into the manual
queue will make the request cancelable.

d
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Michelson
Rachel-CRK007
Sent: Thursday, January 05, 2012 3:13 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] best way to kill a FileRead()?

Hello all,

I am working with an SDIO-based device; an application using it is
supposed to block in a ReadFile() until a message is available from the
device. The device generates an interrupt when a message is available.
The application spends a long time waiting for ReadFile() to return, and
chances are that the user will kill the application. What do I need to do
to gracefully handle aborting the read request?

The current implementation is as follows: the interrupt service callback
sets an event flag using KeSetEvent(). The queue’s EvtIoRead calls
KeWaitForSingleObject() on this flag thus blocking, and only performs the
actual read after the event flag is set by the interrupt service callback.

I set Alertable parameter to TRUE in the KeWaitForSingleObject(), and this
seems to make the WaitForSingleObject() exit so that I could complete
EvtIoRead(). Without this, the thread never died and I had to cycle power
on the machine. Is this all that is needed? Or, do I need to mark the
request as cancellable and implement a cancellation callback?

Thanks
Rachel


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

I agree. Your whole design ignores the fact that I/O is essentially an
asynchronous event-driven mechanism. You mark the IRP as pending, put it
in a queue (and the order is important!) the return STATUS_PENDING. As
already explained, using the queue makes the IRP cancelable, but then you
must expect this cancellation to have happened and plan accordingly, so
that if the device eventually does interrupt you won’t do something bad
when the queue is empty, and get a BSOD. Essentially, you came up with a
needlessly complex solution to what is a well-understood problem, and then
painted yourself into a corner by trying to make it work, which is not
feasible. A device with potentially unbounded latency must always be
prepared to have an active IRP cancelled, which is what will happen if the
process terminates. Note also that whatever solution you implement must
react to asynchronous I/O with multiple IRPs pending (but typically only
one active). KMDF handles cancellation of pending IRPs for you, but in
the case of an active IRP, which has already started a hardware
transaction, it may be desirable, or even mandatory, to tell the device to
terminate the opertion (e.g. direct-mode I/O would find the pages no
longer locked down, and thus DMA could write random trash to random pages
unless the hardware operation is aborted)
joe

The process will never die as long as it has outstanding IO, so all IOOPs
(IRP) must be cancelled or completed. Implementing cancel is by far the
best method as it ensures that your driver responds to the users desire and
not the other way around. Use the KMDF queues and you have almost no work
to do to support it too; and then if the application changes from sync
ReadFile to overlapped IO or another model, you don’t create an artificial
bottleneck in the system either.

“Michelson Rachel-CRK007” wrote in message news:xxxxx@ntdev…

Hello all,

I am working with an SDIO-based device; an application using it is
supposed to block in a ReadFile() until a message is available from the
device. The device generates an interrupt when a message is available.
The application spends a long time waiting for ReadFile() to return, and
chances are that the user will kill the application. What do I need to
do to gracefully handle aborting the read request?

The current implementation is as follows: the interrupt service callback
sets an event flag using KeSetEvent(). The queue’s EvtIoRead calls
KeWaitForSingleObject() on this flag thus blocking, and only performs
the actual read after the event flag is set by the interrupt service
callback.

I set Alertable parameter to TRUE in the KeWaitForSingleObject(), and
this seems to make the WaitForSingleObject() exit so that I could
complete EvtIoRead(). Without this, the thread never died and I had to
cycle power on the machine. Is this all that is needed? Or, do I need
to mark the request as cancellable and implement a cancellation
callback?

Thanks
Rachel

Thank you all for your help.

I now have a separate manual queue for pending read requests as was
suggested, which solved the problem of killing pending reads.

With the two queues, can one thread of the application be blocked in
ReadFile() while another thread has its WriteFile() serviced?

My WriteFile() now hangs until killed. Is it possible that the pending
read still blocks *something*? Am I missing a configuration? Or is there
something special I have to do when creating the file?

!wdflogdump shows IRP_MJ_READ dispatching, but the IRP_MJ_WRITE is not
there.!wdfQueue shows a pending read request in the manual queue and 0
requests in the default queue (the one that services the write request).
The breakpoint in EvtIoWrite of the default queue is not hit.

I have verified that a WriteFile() works when it is not happening during
a pedning ReadFile(). I have tried both forwarding the reads to the
manual queue from the default queue, and configuring the manual queue to
dispatch read requests on its own.

The file is created with CreateFile() with
FILE_SHARE_READ|FILE_SHARE_WRITE. There does not seem to be a need to
use OVERLAPPED, from what I read about it.

Thank you!
Rachel

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@flounder.com
Sent: Friday, January 06, 2012 12:16 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] best way to kill a FileRead()?

You don’t want an altertable wait. You pretty much never want to
infinitely block your dispatching function. Instead, forward the read
to
manual queue. When the interrupt/message occurs, in your DPC pull the
request out the manual queue and complete it. Putting it into the
manual
queue will make the request cancelable.

d
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Michelson
Rachel-CRK007
Sent: Thursday, January 05, 2012 3:13 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] best way to kill a FileRead()?

Hello all,

I am working with an SDIO-based device; an application using it is
supposed to block in a ReadFile() until a message is available from
the
device. The device generates an interrupt when a message is available.
The application spends a long time waiting for ReadFile() to return,
and
chances are that the user will kill the application. What do I need to
do
to gracefully handle aborting the read request?

The current implementation is as follows: the interrupt service
callback
sets an event flag using KeSetEvent(). The queue’s EvtIoRead calls
KeWaitForSingleObject() on this flag thus blocking, and only performs
the
actual read after the event flag is set by the interrupt service
callback.

I set Alertable parameter to TRUE in the KeWaitForSingleObject(), and
this
seems to make the WaitForSingleObject() exit so that I could complete
EvtIoRead(). Without this, the thread never died and I had to cycle
power
on the machine. Is this all that is needed? Or, do I need to mark
the
request as cancellable and implement a cancellation callback?

Thanks
Rachel


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

I agree. Your whole design ignores the fact that I/O is essentially an
asynchronous event-driven mechanism. You mark the IRP as pending, put
it
in a queue (and the order is important!) the return STATUS_PENDING. As
already explained, using the queue makes the IRP cancelable, but then
you
must expect this cancellation to have happened and plan accordingly, so
that if the device eventually does interrupt you won’t do something bad
when the queue is empty, and get a BSOD. Essentially, you came up with
a
needlessly complex solution to what is a well-understood problem, and
then
painted yourself into a corner by trying to make it work, which is not
feasible. A device with potentially unbounded latency must always be
prepared to have an active IRP cancelled, which is what will happen if
the
process terminates. Note also that whatever solution you implement must
react to asynchronous I/O with multiple IRPs pending (but typically only
one active). KMDF handles cancellation of pending IRPs for you, but in
the case of an active IRP, which has already started a hardware
transaction, it may be desirable, or even mandatory, to tell the device
to
terminate the opertion (e.g. direct-mode I/O would find the pages no
longer locked down, and thus DMA could write random trash to random
pages
unless the hardware operation is aborted)
joe


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

if you open a file handle without OVERLAPPED, the io manager restricts the file handle to one pending io at a time. so in this case, the READ is the one pending IO and then the write IO request is pended at the io manager (above your driver) until the read completes. For two or more IO operations to be active at once, you must open the file as OVERLAPPED and then handle each io as an async request (call GetOverlappedResult, wait on the handle in the OVERLAPPED as appropriate, etc)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Michelson Rachel-CRK007
Sent: Tuesday, January 10, 2012 2:45 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] best way to kill a FileRead()?

Thank you all for your help.

I now have a separate manual queue for pending read requests as was suggested, which solved the problem of killing pending reads.

With the two queues, can one thread of the application be blocked in
ReadFile() while another thread has its WriteFile() serviced?

My WriteFile() now hangs until killed. Is it possible that the pending read still blocks *something*? Am I missing a configuration? Or is there something special I have to do when creating the file?

!wdflogdump shows IRP_MJ_READ dispatching, but the IRP_MJ_WRITE is not there.!wdfQueue shows a pending read request in the manual queue and 0 requests in the default queue (the one that services the write request).
The breakpoint in EvtIoWrite of the default queue is not hit.

I have verified that a WriteFile() works when it is not happening during a pedning ReadFile(). I have tried both forwarding the reads to the manual queue from the default queue, and configuring the manual queue to dispatch read requests on its own.

The file is created with CreateFile() with FILE_SHARE_READ|FILE_SHARE_WRITE. There does not seem to be a need to use OVERLAPPED, from what I read about it.

Thank you!
Rachel

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@flounder.com
Sent: Friday, January 06, 2012 12:16 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] best way to kill a FileRead()?

You don’t want an altertable wait. You pretty much never want to
infinitely block your dispatching function. Instead, forward the read
to
manual queue. When the interrupt/message occurs, in your DPC pull the
request out the manual queue and complete it. Putting it into the
manual
queue will make the request cancelable.

d
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Michelson
Rachel-CRK007
Sent: Thursday, January 05, 2012 3:13 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] best way to kill a FileRead()?

Hello all,

I am working with an SDIO-based device; an application using it is
supposed to block in a ReadFile() until a message is available from
the
device. The device generates an interrupt when a message is available.
The application spends a long time waiting for ReadFile() to return,
and
chances are that the user will kill the application. What do I need to
do
to gracefully handle aborting the read request?

The current implementation is as follows: the interrupt service
callback
sets an event flag using KeSetEvent(). The queue’s EvtIoRead calls
KeWaitForSingleObject() on this flag thus blocking, and only performs
the
actual read after the event flag is set by the interrupt service
callback.

I set Alertable parameter to TRUE in the KeWaitForSingleObject(), and
this
seems to make the WaitForSingleObject() exit so that I could complete
EvtIoRead(). Without this, the thread never died and I had to cycle
power
on the machine. Is this all that is needed? Or, do I need to mark
the
request as cancellable and implement a cancellation callback?

Thanks
Rachel


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

I agree. Your whole design ignores the fact that I/O is essentially an asynchronous event-driven mechanism. You mark the IRP as pending, put it in a queue (and the order is important!) the return STATUS_PENDING. As already explained, using the queue makes the IRP cancelable, but then you must expect this cancellation to have happened and plan accordingly, so that if the device eventually does interrupt you won’t do something bad when the queue is empty, and get a BSOD. Essentially, you came up with a needlessly complex solution to what is a well-understood problem, and then painted yourself into a corner by trying to make it work, which is not feasible. A device with potentially unbounded latency must always be prepared to have an active IRP cancelled, which is what will happen if the process terminates. Note also that whatever solution you implement must react to asynchronous I/O with multiple IRPs pending (but typically only one active). KMDF handles cancellation of pending IRPs for you, but in the case of an active IRP, which has already started a hardware transaction, it may be desirable, or even mandatory, to tell the device to terminate the opertion (e.g. direct-mode I/O would find the pages no longer locked down, and thus DMA could write random trash to random pages unless the hardware operation is aborted)
joe


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