KMDF handling of IRP_MJ_CLOSE - can it be pended?

I have the (perhaps odd) situation of needing to delay the completion of
IRP_MJ_CLOSE while my device cleans up a bit of state. I do not want to
wait syncronously in an EvtFileClose handler because (as I understand it)
the syncronization scope ‘lock’ of my device will be held while this
callback is processed (perhaps I am wrong about this). I need to be able to
acquire the ‘lock’ associated with my device in the completion code and thus
I believe attempting to do so would lead to a deadlock.

On the IRP_MJ_CREATE side no problem, the EvtDeviceFileCreate() callback
gives my code the WDFREQUEST to complete which means I can stick it in a
manual queue and get around to completing it later - which is exactly what I
do.

I would basically like to do the same thing for IRP_MJ_CLOSE and have not
found a perfect solution nor completely understand the tradeoffs of how to
get this done.

For instance, does it make sense to forego the framework ‘file object’
support and default handling of IRP_MJ_CREATE/CLEANUP/CLOSE and instead
configure the an EvtIoDefault() handler for my default (parallel) queue and
catch IRP_MJ_CREATE/CLEANUP/CLOSE as WDFREQUESTs directly instead of via the
framework file object notifications? If I do that, can I stick those
requests back into the framework somehow (or should I, or should I not)?

In this particular driver I don’t actually have any need to hold onto “file
object” context and so I can do without the framework file object handling.
In other drivers I can imagine wanting the framework support of file objects
*and* being able to pend a cleanup or close.

TIA for any ideas or pointers.

-dave

David R. Cattley
Consulting Engineer
Systems Software Development

Why do you hang onto the close vs cleanup irp? The cleanup irp is the
one in the context of the application, the close irp can come in the
system context. I would forgo built in locking and then block in
EvtFileCleanup. Really needed to do this with the built in locking, set
a preprocess routine for IRP_MJ_CLEANUP, block in the preprocess routine
and when your wait is satisfied, send the IRP to KMDF for further
processing.

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David R. Cattley
Sent: Monday, April 23, 2007 6:15 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

I have the (perhaps odd) situation of needing to delay the completion of
IRP_MJ_CLOSE while my device cleans up a bit of state. I do not want to
wait syncronously in an EvtFileClose handler because (as I understand
it) the syncronization scope ‘lock’ of my device will be held while this
callback is processed (perhaps I am wrong about this). I need to be
able to acquire the ‘lock’ associated with my device in the completion
code and thus I believe attempting to do so would lead to a deadlock.

On the IRP_MJ_CREATE side no problem, the EvtDeviceFileCreate() callback
gives my code the WDFREQUEST to complete which means I can stick it in a
manual queue and get around to completing it later - which is exactly
what I do.

I would basically like to do the same thing for IRP_MJ_CLOSE and have
not found a perfect solution nor completely understand the tradeoffs of
how to get this done.

For instance, does it make sense to forego the framework ‘file object’
support and default handling of IRP_MJ_CREATE/CLEANUP/CLOSE and instead
configure the an EvtIoDefault() handler for my default (parallel) queue
and catch IRP_MJ_CREATE/CLEANUP/CLOSE as WDFREQUESTs directly instead of
via the framework file object notifications? If I do that, can I stick
those requests back into the framework somehow (or should I, or should I
not)?

In this particular driver I don’t actually have any need to hold onto
“file object” context and so I can do without the framework file object
handling. In other drivers I can imagine wanting the framework support
of file objects *and* being able to pend a cleanup or close.

TIA for any ideas or pointers.

-dave

David R. Cattley

Consulting Engineer

Systems Software Development


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

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

Doron,

This makes me think I don’t quite understand the implications of combination
of WdfSyncronizationScopeDevice combined with WdfExecutionLevelPassive.
With that combination I am expecting that the framework will ensure that my
callback entries will be called at PASSIVE_LEVEL. I also expected that to
serialize the callbacks, the framework would be acquiring the ‘lock’
associated with the WDFDEVICE which owns the queue(s), file objects, work
items, etc. which have callbacks associated with them.

I am under the impression that if I wish to syncronize an external callback
from another source that is at PASSIVE_LEVEL to device scope that I would
need to acquire the ‘lock’ associated with the WDFDEVICE using
WdfObjectAcquireLock().

If the dispatch of IRP_MJ_CLEANUP (or IRP_MJ_CLOSE) blocks in the framework
callback EvtFileCleanup, wont the WDFDEVICE ‘lock’ be held during that
block? If so, that would require that any state that needs to be modified
be outside of the syncronization scope of framework automatic
syncronization.

I can build that, I just figured it far more convenient to complete the
IRP_MJ_CLEANUP (or close) asyncronously instead of holding a lock while
blocking a dispatch just waiting.

I am in the situation of interfacing to a third-party component that
requires PASSIVE_LEVEL execution only. The combination of
WdfSyncronizationScopeDevice and WdfExecutionLevelPassive seemed to be the
perfect way to satisfy this and avoid constructing a workitem based
syncronization scheme directly and explicit syncronization (locking).

I will give the preprocess route a try but here I believe I must *not* delay
the framework handling of IRP_MJ_CLEANUP because doing so will break the
contract of cleanup being processed by the framework in the ‘handle owner’
thread context. Am I correct to assume that the framework is relying on
the I/O manager to dispatch the IRP_MJ_CLEANUP in that context and does no
further work to defend against some driver diverting the executing context
to another thread?

Thanks for the ideas.

Regards,
-dave


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Monday, April 23, 2007 9:29 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

Why do you hang onto the close vs cleanup irp? The cleanup irp is the one
in the context of the application, the close irp can come in the system
context. I would forgo built in locking and then block in EvtFileCleanup.
Really needed to do this with the built in locking, set a preprocess routine
for IRP_MJ_CLEANUP, block in the preprocess routine and when your wait is
satisfied, send the IRP to KMDF for further processing.

d

KMDF does not assert anything about the context that IRP_MJ_CLEANUP is
processed in, but others in the stack might assume the context is
correct. IRP_MJ_CLEANUP’s contract is that this is the last IRP
guaranteed to be in the calling process’s context and this is where you
do cleanup. KMDF does not provide a native way to pend the cleanup or
close IRPs, they are supposed to be synchronously processed. My
suggestion of dropping KMDF locking is b/c you are starting to move
outside of the built in locking capabilities and you will need to manage
your own state now b/c you are dropping into WDM IRP preprocessing.

Is another KM component sending you I/O? If not and it is only a user
mode application which is opening a handle and sending i/o, the passive
execution level is not needed if you choose not to use device level
locking. By choosing no locking and no execution level, i/o will still
be presented at passive if it comes from a UM application.

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David R. Cattley
Sent: Tuesday, April 24, 2007 4:59 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

Doron,

This makes me think I don’t quite understand the implications of
combination of WdfSyncronizationScopeDevice combined with
WdfExecutionLevelPassive. With that combination I am expecting that
the framework will ensure that my callback entries will be called at
PASSIVE_LEVEL. I also expected that to serialize the callbacks, the
framework would be acquiring the ‘lock’ associated with the WDFDEVICE
which owns the queue(s), file objects, work items, etc. which have
callbacks associated with them.

I am under the impression that if I wish to syncronize an external
callback from another source that is at PASSIVE_LEVEL to device scope
that I would need to acquire the ‘lock’ associated with the WDFDEVICE
using WdfObjectAcquireLock().

If the dispatch of IRP_MJ_CLEANUP (or IRP_MJ_CLOSE) blocks in the
framework callback EvtFileCleanup, wont the WDFDEVICE ‘lock’ be held
during that block? If so, that would require that any state that needs
to be modified be outside of the syncronization scope of framework
automatic syncronization.

I can build that, I just figured it far more convenient to complete the
IRP_MJ_CLEANUP (or close) asyncronously instead of holding a lock while
blocking a dispatch just waiting.

I am in the situation of interfacing to a third-party component that
requires PASSIVE_LEVEL execution only. The combination of
WdfSyncronizationScopeDevice and WdfExecutionLevelPassive seemed to be
the perfect way to satisfy this and avoid constructing a workitem based
syncronization scheme directly and explicit syncronization (locking).

I will give the preprocess route a try but here I believe I must *not*
delay the framework handling of IRP_MJ_CLEANUP because doing so will
break the contract of cleanup being processed by the framework in the
‘handle owner’ thread context. Am I correct to assume that the
framework is relying on the I/O manager to dispatch the IRP_MJ_CLEANUP
in that context and does no further work to defend against some driver
diverting the executing context to another thread?

Thanks for the ideas.

Regards,

-dave


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Monday, April 23, 2007 9:29 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

Why do you hang onto the close vs cleanup irp? The cleanup irp is the
one in the context of the application, the close irp can come in the
system context. I would forgo built in locking and then block in
EvtFileCleanup. Really needed to do this with the built in locking, set
a preprocess routine for IRP_MJ_CLEANUP, block in the preprocess routine
and when your wait is satisfied, send the IRP to KMDF for further
processing.

d


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

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

Doron,

Again, thanks. I am convinced. I will not try to pend the IRP_MJ_CLEANUP
(or IRP_MJ_CLOSE). I do want to finish with a more complete understanding
of the locking the framework is using, however. Permit me some direct
questions :slight_smile:

  1. On a WDM preprocess callback, has the framework applied its
    syncronization? In other words, is this callback syncronized to the level
    and scope specified for the WDFDEVICE? Perhaps it is not and this is what
    you mean by

>move outside of the built in locking capabilities and you will need to
manage your own state now b/c you are dropping into WDM IRP preprocessing

  1. On EvtFileCleanup() and EvtFileClose() is the framework holding the lock
    associated with the WDFDEVICE? Is this the same lock that is acquired by
    WdfObjectAcquireLock()?

  2. Will a WDFWORKITEM that is a child of the WDFDEVICE and that inherited
    the syncronization scope from the WDFDEVICE acquire the WDFDEVICE ‘lock’ as
    part of its syncronization behavior?

Thanks,
-dave


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Tuesday, April 24, 2007 12:41 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

KMDF does not assert anything about the context that IRP_MJ_CLEANUP is
processed in, but others in the stack might assume the context is correct.
IRP_MJ_CLEANUP?s contract is that this is the last IRP guaranteed to be in
the calling process?s context and this is where you do cleanup. KMDF does
not provide a native way to pend the cleanup or close IRPs, they are
supposed to be synchronously processed. My suggestion of dropping KMDF
locking is b/c you are starting to move outside of the built in locking
capabilities and you will need to manage your own state now b/c you are
dropping into WDM IRP preprocessing.

Is another KM component sending you I/O? If not and it is only a user mode
application which is opening a handle and sending i/o, the passive execution
level is not needed if you choose not to use device level locking. By
choosing no locking and no execution level, i/o will still be presented at
passive if it comes from a UM application.

d

  1. The framework has not applied its synchronization. The whole
    point of the preprocess routines is that you can escape whatever KMDF is
    doing and get to the underlying WDM IRP without KMDF doing a thing for
    you

  2. Yes and yes

  3. Yes (if you chose device wide locking)

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David R. Cattley
Sent: Tuesday, April 24, 2007 10:47 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

Doron,

Again, thanks. I am convinced. I will not try to pend the
IRP_MJ_CLEANUP (or IRP_MJ_CLOSE). I do want to finish with a more
complete understanding of the locking the framework is using, however.
Permit me some direct questions :slight_smile:

  1. On a WDM preprocess callback, has the framework applied its
    syncronization? In other words, is this callback syncronized to the
    level and scope specified for the WDFDEVICE? Perhaps it is not and this
    is what you mean by

>move outside of the built in locking capabilities and you will need to
manage your own state now b/c you are dropping into WDM IRP
preprocessing

  1. On EvtFileCleanup() and EvtFileClose() is the framework holding the
    lock associated with the WDFDEVICE? Is this the same lock that is
    acquired by WdfObjectAcquireLock()?

  2. Will a WDFWORKITEM that is a child of the WDFDEVICE and that
    inherited the syncronization scope from the WDFDEVICE acquire the
    WDFDEVICE ‘lock’ as part of its syncronization behavior?

Thanks,

-dave


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Tuesday, April 24, 2007 12:41 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

KMDF does not assert anything about the context that IRP_MJ_CLEANUP is
processed in, but others in the stack might assume the context is
correct. IRP_MJ_CLEANUP’s contract is that this is the last IRP
guaranteed to be in the calling process’s context and this is where you
do cleanup. KMDF does not provide a native way to pend the cleanup or
close IRPs, they are supposed to be synchronously processed. My
suggestion of dropping KMDF locking is b/c you are starting to move
outside of the built in locking capabilities and you will need to manage
your own state now b/c you are dropping into WDM IRP preprocessing.

Is another KM component sending you I/O? If not and it is only a user
mode application which is opening a handle and sending i/o, the passive
execution level is not needed if you choose not to use device level
locking. By choosing no locking and no execution level, i/o will still
be presented at passive if it comes from a UM application.

d


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

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

Thanks again.
-dave


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Tuesday, April 24, 2007 2:14 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

  1. The framework has not applied its synchronization. The whole point
    of the preprocess routines is that you can escape whatever KMDF is doing and
    get to the underlying WDM IRP without KMDF doing a thing for you

  2. Yes and yes

  3. Yes (if you chose device wide locking)

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David R. Cattley
Sent: Tuesday, April 24, 2007 10:47 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

Doron,

Again, thanks. I am convinced. I will not try to pend the IRP_MJ_CLEANUP
(or IRP_MJ_CLOSE). I do want to finish with a more complete understanding
of the locking the framework is using, however. Permit me some direct
questions :slight_smile:

  1. On a WDM preprocess callback, has the framework applied its
    syncronization? In other words, is this callback syncronized to the level
    and scope specified for the WDFDEVICE? Perhaps it is not and this is what
    you mean by

>move outside of the built in locking capabilities and you will need to
manage your own state now b/c you are dropping into WDM IRP preprocessing

  1. On EvtFileCleanup() and EvtFileClose() is the framework holding the lock
    associated with the WDFDEVICE? Is this the same lock that is acquired by
    WdfObjectAcquireLock()?

  2. Will a WDFWORKITEM that is a child of the WDFDEVICE and that inherited
    the syncronization scope from the WDFDEVICE acquire the WDFDEVICE ‘lock’ as
    part of its syncronization behavior?

Thanks,

-dave


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Tuesday, April 24, 2007 12:41 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] KMDF handling of IRP_MJ_CLOSE - can it be pended?

KMDF does not assert anything about the context that IRP_MJ_CLEANUP is
processed in, but others in the stack might assume the context is correct.
IRP_MJ_CLEANUP?s contract is that this is the last IRP guaranteed to be in
the calling process?s context and this is where you do cleanup. KMDF does
not provide a native way to pend the cleanup or close IRPs, they are
supposed to be synchronously processed. My suggestion of dropping KMDF
locking is b/c you are starting to move outside of the built in locking
capabilities and you will need to manage your own state now b/c you are
dropping into WDM IRP preprocessing.

Is another KM component sending you I/O? If not and it is only a user mode
application which is opening a handle and sending i/o, the passive execution
level is not needed if you choose not to use device level locking. By
choosing no locking and no execution level, i/o will still be presented at
passive if it comes from a UM application.

d


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

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


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

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