Cancel Safe Queues and IRP Context

Hi.
Three questions about using the Context parameter in IoCsqInsertIrp and
IoCsqRemoveIrp:

  1. Do I need to give the same structure instance when inserting the Irp and
    when removing it or can give two different structures that have the same
    data filled in them?
    I’m wondering if I should send the pointer to the structure to my hardware
    and free the structure when the IO completes or send the data of the
    structure itself, free the structure immediately and give the structure I
    receive from the hardware when I remove the Irp.

  2. Say it has to be a structure with the exact same address - In my driver,
    if the hardware does not return a result after 1 minute I complete the Irp
    with STATUS_TIMEOUT and delete the context.
    What if I get a reply from the hardware after 2 minutes and then try to
    remove the Irp with the context pointer I received from the hardware (which
    is already freed)?

Since IoCsqRemoveIrp calls CsqRemoveIrp and gives the Irp address as
parameter, my guess is that IoCsqRemoveIrp peeks into the context to get the
Irp address and that in case the Irp already timedout I’ll get a nice
bug-check…
Do I have to use CsqInsertIrpEx and IoCsqRemoveNextIrp with my own
driver-defined peek-context and have CsqPeekNextIrp not touch the context
until I find an Irp that points to it?

  1. Say it has to be a structure with the exact same address - What if the
    driver who issued the Irp cancels it? CsqCompleteCanceledIrp does not
    receive the context as parameter, how can I free the context?
    My guess is that the address of the context is stored in DriverContext[3] so
    I probably can just free it (hoping it’s not cleared before it is passed to
    my routine and that it will not be moved to a different location in future
    versions, which is probably not wise…). Is there another way? Is this a
    design mistake?

Thanks,
Shahar

If you want to cancel a request that you’ve sent to your device, then
you should probably tell the device to stop processing it before
completing it. Particularly if your device uses DMA (since it could
transfer data into buffers which have been freed).

When you want to time-out a request you would first talk to the device
to make sure it’s not going to try and complete it later. Either that
or you need some intermediate table of request “handles” that you can
hand to the hardware which will allow you to find out if you’ve already
aborted the IRP that started the request. If you have then you just
dump the completion on the floor. If you haven’t then you use that
context to pull the request out of the queue.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Sunday, February 20, 2005 9:45 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Cancel Safe Queues and IRP Context

Hi.
Three questions about using the Context parameter in IoCsqInsertIrp and
IoCsqRemoveIrp:

  1. Do I need to give the same structure instance when inserting the Irp
    and when removing it or can give two different structures that have the
    same data filled in them?
    I’m wondering if I should send the pointer to the structure to my
    hardware and free the structure when the IO completes or send the data
    of the structure itself, free the structure immediately and give the
    structure I receive from the hardware when I remove the Irp.

  2. Say it has to be a structure with the exact same address - In my
    driver, if the hardware does not return a result after 1 minute I
    complete the Irp with STATUS_TIMEOUT and delete the context.
    What if I get a reply from the hardware after 2 minutes and then try to
    remove the Irp with the context pointer I received from the hardware
    (which is already freed)?

Since IoCsqRemoveIrp calls CsqRemoveIrp and gives the Irp address as
parameter, my guess is that IoCsqRemoveIrp peeks into the context to get
the Irp address and that in case the Irp already timedout I’ll get a
nice bug-check…
Do I have to use CsqInsertIrpEx and IoCsqRemoveNextIrp with my own
driver-defined peek-context and have CsqPeekNextIrp not touch the
context until I find an Irp that points to it?

  1. Say it has to be a structure with the exact same address - What if
    the driver who issued the Irp cancels it? CsqCompleteCanceledIrp does
    not receive the context as parameter, how can I free the context?
    My guess is that the address of the context is stored in
    DriverContext[3] so I probably can just free it (hoping it’s not cleared
    before it is passed to my routine and that it will not be moved to a
    different location in future versions, which is probably not wise…).
    Is there another way? Is this a design mistake?

Thanks,
Shahar


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

To answer the original questions

  1. yes, it needs to be the same pointer value, ie the same address

  2. peter answered this. You need to tell the hw to stop accessing the
    Buffer in the irp, otherwise you can’t complete the irp

  3. store the context in one of the other DriverContext fields (0-2)

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter Wieland
Sent: Sunday, February 20, 2005 1:29 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Cancel Safe Queues and IRP Context

If you want to cancel a request that you’ve sent to your device, then
you should probably tell the device to stop processing it before
completing it. Particularly if your device uses DMA (since it could
transfer data into buffers which have been freed).

When you want to time-out a request you would first talk to the device
to make sure it’s not going to try and complete it later. Either that
or you need some intermediate table of request “handles” that you can
hand to the hardware which will allow you to find out if you’ve already
aborted the IRP that started the request. If you have then you just
dump the completion on the floor. If you haven’t then you use that
context to pull the request out of the queue.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Sunday, February 20, 2005 9:45 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Cancel Safe Queues and IRP Context

Hi.
Three questions about using the Context parameter in IoCsqInsertIrp and
IoCsqRemoveIrp:

  1. Do I need to give the same structure instance when inserting the Irp
    and when removing it or can give two different structures that have the
    same data filled in them?
    I’m wondering if I should send the pointer to the structure to my
    hardware and free the structure when the IO completes or send the data
    of the structure itself, free the structure immediately and give the
    structure I receive from the hardware when I remove the Irp.

  2. Say it has to be a structure with the exact same address - In my
    driver, if the hardware does not return a result after 1 minute I
    complete the Irp with STATUS_TIMEOUT and delete the context.
    What if I get a reply from the hardware after 2 minutes and then try to
    remove the Irp with the context pointer I received from the hardware
    (which is already freed)?

Since IoCsqRemoveIrp calls CsqRemoveIrp and gives the Irp address as
parameter, my guess is that IoCsqRemoveIrp peeks into the context to get
the Irp address and that in case the Irp already timedout I’ll get a
nice bug-check…
Do I have to use CsqInsertIrpEx and IoCsqRemoveNextIrp with my own
driver-defined peek-context and have CsqPeekNextIrp not touch the
context until I find an Irp that points to it?

  1. Say it has to be a structure with the exact same address - What if
    the driver who issued the Irp cancels it? CsqCompleteCanceledIrp does
    not receive the context as parameter, how can I free the context?
    My guess is that the address of the context is stored in
    DriverContext[3] so I probably can just free it (hoping it’s not cleared
    before it is passed to my routine and that it will not be moved to a
    different location in future versions, which is probably not wise…).
    Is there another way? Is this a design mistake?

Thanks,
Shahar


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thank you Peter and Doron.

Sadly there is no way to cancel requests that were already sent to the
hardware.
This is not a problem, though, since both the method I suggested (using
CsqInsertIrpEx and IoCsqRemoveNextIrp with my own driver-defined
peek-context) and the method Peter suggested (some intermediate table of
request “handles”) will solve my problem:

  1. When a request times out my driver just notifies the application. This
    will make the application do the operation itself using a software
    implementation (this is possible, but much less eficient). If the hardware
    completes the request at a later time I just ignore it.

  2. When my application is no longer interested in the answer for a request
    it can just request the driver to free all the data structures it has
    associated with the request and cancel the Irp. This way it can be sure no
    one will call the completion routine and access all the freed data
    structures. Again, when the hardware completes the request I just ignore it.

The hardware does not access any information in the Irp, it simply has a
copy of the request (and ofcourse, a context I can use to remove the Irp
from the CSQ when the operation completes) so when freeing the Irp i will
not cause any problems in the hardware.

Using the method I’ve suggested sounds more simple to me since I don’t need
to manage another table and it only costs me a little more complexity in my
CSQ routines.

Thanks,
Shahar

“Doron Holan” wrote in message
news:xxxxx@ntdev…
To answer the original questions
1) yes, it needs to be the same pointer value, ie the same address

2) peter answered this. You need to tell the hw to stop accessing the
Buffer in the irp, otherwise you can’t complete the irp

3) store the context in one of the other DriverContext fields (0-2)

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter Wieland
Sent: Sunday, February 20, 2005 1:29 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Cancel Safe Queues and IRP Context

If you want to cancel a request that you’ve sent to your device, then
you should probably tell the device to stop processing it before
completing it. Particularly if your device uses DMA (since it could
transfer data into buffers which have been freed).

When you want to time-out a request you would first talk to the device
to make sure it’s not going to try and complete it later. Either that
or you need some intermediate table of request “handles” that you can
hand to the hardware which will allow you to find out if you’ve already
aborted the IRP that started the request. If you have then you just
dump the completion on the floor. If you haven’t then you use that
context to pull the request out of the queue.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Shahar Talmi
Sent: Sunday, February 20, 2005 9:45 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Cancel Safe Queues and IRP Context

Hi.
Three questions about using the Context parameter in IoCsqInsertIrp and
IoCsqRemoveIrp:

1) Do I need to give the same structure instance when inserting the Irp
and when removing it or can give two different structures that have the
same data filled in them?
I’m wondering if I should send the pointer to the structure to my
hardware and free the structure when the IO completes or send the data
of the structure itself, free the structure immediately and give the
structure I receive from the hardware when I remove the Irp.

2) Say it has to be a structure with the exact same address - In my
driver, if the hardware does not return a result after 1 minute I
complete the Irp with STATUS_TIMEOUT and delete the context.
What if I get a reply from the hardware after 2 minutes and then try to
remove the Irp with the context pointer I received from the hardware
(which is already freed)?

Since IoCsqRemoveIrp calls CsqRemoveIrp and gives the Irp address as
parameter, my guess is that IoCsqRemoveIrp peeks into the context to get
the Irp address and that in case the Irp already timedout I’ll get a
nice bug-check…
Do I have to use CsqInsertIrpEx and IoCsqRemoveNextIrp with my own
driver-defined peek-context and have CsqPeekNextIrp not touch the
context until I find an Irp that points to it?

3) Say it has to be a structure with the exact same address - What if
the driver who issued the Irp cancels it? CsqCompleteCanceledIrp does
not receive the context as parameter, how can I free the context?
My guess is that the address of the context is stored in
DriverContext[3] so I probably can just free it (hoping it’s not cleared
before it is passed to my routine and that it will not be moved to a
different location in future versions, which is probably not wise…).
Is there another way? Is this a design mistake?

Thanks,
Shahar


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com