In the WDM book, I see the way to send an asynchronous IRP to a lower
driver is to do an IoAcquireRemoveLock(), install a completion
routine, do the IoCallDriver(), and do an IoReleaseRemoveLock() in the
completion routine. The remove lock is meant to prevent a PNP remove
from being forwarded to the lower driver while it's processing the
IRP, but won't the lower driver still be blocked in its call to
IoCompleteRequest() when the completion routine releases the remove
lock? That is, couldn't the other driver then be removed before its
completely done with the IRP?

I can think of two cases:

If the lower driver is calling IoCompleteRequest() from a worker
thread or a DPC, then it should be expected that thread or DPC will be
allowed to finish before the driver is removed. This case should be
okay.

If the lower driver is calling IoCompleteRequest() from its
dispatch routine, won't the completion routine remove the lock before
the dispatch routine returns so the lower driver could be removed
before the next few instructions that return from its dispatch
routine? This case seems to require the same extra reference solution
the WDM book mentions that initially confused me for a few days. I
think the remove lock needs to be acquired twice and released in both
the completion routine and after the call to IoCallDriver(), to make
sure the lower driver can't be removed until they're both finished
(whichever finishes first). As an alternative, I guess an extra
reference would work too.




(Of course, this alternative makes me wonder what are the advantages
of using a remove lock vs. taking extra references. They can both be
used to keep a device object in memory, but I guess the remove lock
can be used to start failing new IRPs at a certain point in the
removal process, so the removal goes faster. It doesn't actually
prevent new IRPs from being received by a dispatch routine. It just
allows them to be quickly completed with error status.)

Re: Asynchronous IRP remove lock race? by Doron

Doron
Wed Sep 13 21:55:01 CDT 2006

the pnp manager holds a ref on each device object in the stack until after
the remove has completed. this will prevent an unload from occurring in the
middle of i/o rundown.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


<BubbaGump> wrote in message
news:6i1hg25dd1g7dg9o1rgqv0g40qhj17unbt@4ax.com...
> In the WDM book, I see the way to send an asynchronous IRP to a lower
> driver is to do an IoAcquireRemoveLock(), install a completion
> routine, do the IoCallDriver(), and do an IoReleaseRemoveLock() in the
> completion routine. The remove lock is meant to prevent a PNP remove
> from being forwarded to the lower driver while it's processing the
> IRP, but won't the lower driver still be blocked in its call to
> IoCompleteRequest() when the completion routine releases the remove
> lock? That is, couldn't the other driver then be removed before its
> completely done with the IRP?
>
> I can think of two cases:
>
> If the lower driver is calling IoCompleteRequest() from a worker
> thread or a DPC, then it should be expected that thread or DPC will be
> allowed to finish before the driver is removed. This case should be
> okay.
>
> If the lower driver is calling IoCompleteRequest() from its
> dispatch routine, won't the completion routine remove the lock before
> the dispatch routine returns so the lower driver could be removed
> before the next few instructions that return from its dispatch
> routine? This case seems to require the same extra reference solution
> the WDM book mentions that initially confused me for a few days. I
> think the remove lock needs to be acquired twice and released in both
> the completion routine and after the call to IoCallDriver(), to make
> sure the lower driver can't be removed until they're both finished
> (whichever finishes first). As an alternative, I guess an extra
> reference would work too.
>
>
>
>
> (Of course, this alternative makes me wonder what are the advantages
> of using a remove lock vs. taking extra references. They can both be
> used to keep a device object in memory, but I guess the remove lock
> can be used to start failing new IRPs at a certain point in the
> removal process, so the removal goes faster. It doesn't actually
> prevent new IRPs from being received by a dispatch routine. It just
> allows them to be quickly completed with error status.)
>



Re: Asynchronous IRP remove lock race? by BubbaGump

BubbaGump
Thu Sep 14 07:26:07 CDT 2006

On Wed, 13 Sep 2006 18:53:03 -0400, BubbaGump <> wrote:

>(Of course, this alternative makes me wonder what are the advantages
>of using a remove lock vs. taking extra references. They can both be
>used to keep a device object in memory, but I guess the remove lock
>can be used to start failing new IRPs at a certain point in the
>removal process, so the removal goes faster. It doesn't actually
>prevent new IRPs from being received by a dispatch routine. It just
>allows them to be quickly completed with error status.)

Okay, this part was just a side curiosity, but I think I noticed the
difference between a reference and a remove lock. The type of
reference I was thinking of from the WDM book was taken out on a file
object (not a device object like I'd first remembered wrongly), and
apparently having a reference to a file object for a device is enough
to prevent a PNP remove from being sent, which means in that case
there's no need for a remove lock to suspend the forwarding of the
remove (because it won't happen at all). So, a reference to a file
object for a device object is basically as good as holding a remove
lock for a device object (of course a remove lock is only useable for
a device in your own device stack).

I still say an asynchronous IRP needs an extra instance of whichever
thing is being used to prevent removal.


Re: Asynchronous IRP remove lock race? by BubbaGump

BubbaGump
Thu Sep 14 07:26:10 CDT 2006

The PNP manager's extra remove references will keep the devices around
until the remove IRP finishes, but I was talking about keeping the
devices around until all their IRPs finish (by making sure the remove
IRP is postponed long enough).




On Wed, 13 Sep 2006 19:55:01 -0700, "Doron Holan [MS]"
<doronh@nospam.microsoft.com> wrote:

>the pnp manager holds a ref on each device object in the stack until after
>the remove has completed. this will prevent an unload from occurring in the
>middle of i/o rundown.
>
>d


Re: Asynchronous IRP remove lock race? by BubbaGump

BubbaGump
Thu Sep 14 07:53:02 CDT 2006

I think of a remove lock as busy bit that stops a driver from freeing
one of its own resources (in this case a lower device object) before
it's done using that resource, in this case after all IRPs sent to
that lower device have come back.




On Thu, 14 Sep 2006 08:26:21 -0400, BubbaGump <> wrote:

>The PNP manager's extra remove references will keep the devices around
>until the remove IRP finishes, but I was talking about keeping the
>devices around until all their IRPs finish (by making sure the remove
>IRP is postponed long enough).
>
>
>
>
>On Wed, 13 Sep 2006 19:55:01 -0700, "Doron Holan [MS]"
><doronh@nospam.microsoft.com> wrote:
>
>>the pnp manager holds a ref on each device object in the stack until after
>>the remove has completed. this will prevent an unload from occurring in the
>>middle of i/o rundown.
>>
>>d


Re: Asynchronous IRP remove lock race? by Maxim

Maxim
Thu Sep 14 10:26:46 CDT 2006

I think that the main goal of the remove lock is to handle the case when
the driver above you in the devnode sends you an IRP created via IoAllocateIrp
and not related to any file object.

The thing is that any IRP initiated by syscall from user mode requires a
file object, and MN_REMOVE_DEVICE will not arrive if there are outstanding file
objects. So, for this case, remove lock is useless.

For the first case, remove lock will suspend the MN_REMOVE_DEVICE
processing till all these non-file-object IRPs are completed.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com

<BubbaGump> wrote in message news:irjig2ld93lvh5durks1l8ieqeaan05lu6@4ax.com...
> I think of a remove lock as busy bit that stops a driver from freeing
> one of its own resources (in this case a lower device object) before
> it's done using that resource, in this case after all IRPs sent to
> that lower device have come back.
>
>
>
>
> On Thu, 14 Sep 2006 08:26:21 -0400, BubbaGump <> wrote:
>
> >The PNP manager's extra remove references will keep the devices around
> >until the remove IRP finishes, but I was talking about keeping the
> >devices around until all their IRPs finish (by making sure the remove
> >IRP is postponed long enough).
> >
> >
> >
> >
> >On Wed, 13 Sep 2006 19:55:01 -0700, "Doron Holan [MS]"
> ><doronh@nospam.microsoft.com> wrote:
> >
> >>the pnp manager holds a ref on each device object in the stack until after
> >>the remove has completed. this will prevent an unload from occurring in the
> >>middle of i/o rundown.
> >>
> >>d
>


Re: Asynchronous IRP remove lock race? by BubbaGump

BubbaGump
Thu Sep 14 10:47:00 CDT 2006

I think the same, and in that case where a remove lock is required and
if another subsidiary IRP is sent asynchronously, that's where I'm
thinking about acquiring/releasing it just one extra time, to handle
the IoCallDriver()/completion race.




On Thu, 14 Sep 2006 19:26:46 +0400, "Maxim S. Shatskih"
<maxim@storagecraft.com> wrote:

> I think that the main goal of the remove lock is to handle the case when
>the driver above you in the devnode sends you an IRP created via IoAllocateIrp
>and not related to any file object.
>
> The thing is that any IRP initiated by syscall from user mode requires a
>file object, and MN_REMOVE_DEVICE will not arrive if there are outstanding file
>objects. So, for this case, remove lock is useless.
>
> For the first case, remove lock will suspend the MN_REMOVE_DEVICE
>processing till all these non-file-object IRPs are completed.


Re: Asynchronous IRP remove lock race? by BubbaGump

BubbaGump
Thu Sep 14 11:20:06 CDT 2006

Instead of "subsidiary IRP", I should have said "subsidiary or
forwarded IRP".




On Thu, 14 Sep 2006 11:47:11 -0400, BubbaGump <> wrote:

>I think the same, and in that case where a remove lock is required and
>if another subsidiary IRP is sent asynchronously, that's where I'm
>thinking about acquiring/releasing it just one extra time, to handle
>the IoCallDriver()/completion race.
>
>
>
>
>On Thu, 14 Sep 2006 19:26:46 +0400, "Maxim S. Shatskih"
><maxim@storagecraft.com> wrote:
>
>> I think that the main goal of the remove lock is to handle the case when
>>the driver above you in the devnode sends you an IRP created via IoAllocateIrp
>>and not related to any file object.
>>
>> The thing is that any IRP initiated by syscall from user mode requires a
>>file object, and MN_REMOVE_DEVICE will not arrive if there are outstanding file
>>objects. So, for this case, remove lock is useless.
>>
>> For the first case, remove lock will suspend the MN_REMOVE_DEVICE
>>processing till all these non-file-object IRPs are completed.