KMDF object context cleanup order

I have a KMDF driver (actually, a bunch of them that share a common wrapper
around stuff like ExAllocatePoolWithTag() and WdfYyyZzz() calls) that
configures a default context for the WDFDEVICE and stores some stuff in
that. Turns out that I need to store a small subset of that information in
a context attached to a WDFDRIVER, and I don't really want to attach the
entire device context, just that small part. Since the code that uses this
particular bit of information could just as easily use the same context
definition for any WDFOBJECT, I had the bright idea that I could use
WdfObjectAllocateContext() to allocate that separate context blob, and
everyone is happy. Except, I can't cleanup the small context I've allocated
until I've cleaned up the default context first.

Are there any guarantees on the order of context cleanup callbacks for a
single object? Or do you only get one context cleanup for a WDFOBJECT,
which would allow me to cleanup both contexts in the order I choose? What
happens if I pass one EvtCleanupCallback in the WDF_OBJECT_ATTRIBUTES I use
to setup the default context, and a different one in the attributes I pass
to WdfObjectAllocateContext()?

Thanks,

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

I know replying to your own post isn't the best form, but I still need an
answer, and only Microsoft can provide one that represents the intended
contract, since the documentation is silent on this, and relying on observed
behavior may not be consistent with what was intended.

This is exactly the kind of situation that Ray Trent's well-reasoned reply
to Bill McKenzie addresses. If I had the source, I could ascertain whether
there is a reasonable expectation of deterministic behavior, or if there is
a potential for random behavior here. Whether I have the source or not, I
can determine what behavior I see empirically.

The important point here is this: Neither conclusion may represent the
contract designer's intent, and relying on it will either result in a broken
driver if MSFT changes the behavior to match the intended contract, or it
will result in MSFT being locked into the current behavior, due to drivers
relying on it.

So could someone from MSFT please state the intent of the contract here?

Is there intended to be an explicit order of cleanup for multiple WDFOBJECT
contexts? FIFO? LIFO? Random? How do default contexts fit into that
order? Last? First? Also random?

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Philip D. Barila" wrote in message
news:xxxxx@ntdev...
>I have a KMDF driver (actually, a bunch of them that share a common wrapper
>around stuff like ExAllocatePoolWithTag() and WdfYyyZzz() calls) that
>configures a default context for the WDFDEVICE and stores some stuff in
>that. Turns out that I need to store a small subset of that information in
>a context attached to a WDFDRIVER, and I don't really want to attach the
>entire device context, just that small part. Since the code that uses this
>particular bit of information could just as easily use the same context
>definition for any WDFOBJECT, I had the bright idea that I could use
>WdfObjectAllocateContext() to allocate that separate context blob, and
>everyone is happy. Except, I can't cleanup the small context I've
>allocated until I've cleaned up the default context first.
>
> Are there any guarantees on the order of context cleanup callbacks for a
> single object? Or do you only get one context cleanup for a WDFOBJECT,
> which would allow me to cleanup both contexts in the order I choose? What
> happens if I pass one EvtCleanupCallback in the WDF_OBJECT_ATTRIBUTES I
> use to setup the default context, and a different one in the attributes I
> pass to WdfObjectAllocateContext()?

I just got back from being gone for a week. The order of cleanup on contexts on one object is not currently defined, I am going to talk with the team to see if we want to commit to documenting the ordering of the context cleanup calls or not....and yes, you are right, the source would tell you what happens, but you would get the same data empirically. The source would not tell you if this is an explicit contract or not anyways, it just makes function calls through function pointers ;).

Where the default context (where default is the context specified in the WDF_OBJECT_ATTRIBUTES during the Create call or the context specified for requests or file objects during device init) is also not documented (but empirically you can see that it is always the first one), I will see if we want to commit to ordering here as well.

And to be clear about ordering overall between different objects (vs your question of different contexts on the same object), the only guarantee is that all child objects of a parent object will be cleaned up before the parent object's cleanup callback is called, there is intentionally no ordering guarantee between siblings who share the same parent.

Thx
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Philip D. Barila
Sent: Monday, September 17, 2007 9:14 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] KMDF object context cleanup order

I know replying to your own post isn't the best form, but I still need an
answer, and only Microsoft can provide one that represents the intended
contract, since the documentation is silent on this, and relying on observed
behavior may not be consistent with what was intended.

This is exactly the kind of situation that Ray Trent's well-reasoned reply
to Bill McKenzie addresses. If I had the source, I could ascertain whether
there is a reasonable expectation of deterministic behavior, or if there is
a potential for random behavior here. Whether I have the source or not, I
can determine what behavior I see empirically.

The important point here is this: Neither conclusion may represent the
contract designer's intent, and relying on it will either result in a broken
driver if MSFT changes the behavior to match the intended contract, or it
will result in MSFT being locked into the current behavior, due to drivers
relying on it.

So could someone from MSFT please state the intent of the contract here?

Is there intended to be an explicit order of cleanup for multiple WDFOBJECT
contexts? FIFO? LIFO? Random? How do default contexts fit into that
order? Last? First? Also random?

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Philip D. Barila" wrote in message
news:xxxxx@ntdev...
>I have a KMDF driver (actually, a bunch of them that share a common wrapper
>around stuff like ExAllocatePoolWithTag() and WdfYyyZzz() calls) that
>configures a default context for the WDFDEVICE and stores some stuff in
>that. Turns out that I need to store a small subset of that information in
>a context attached to a WDFDRIVER, and I don't really want to attach the
>entire device context, just that small part. Since the code that uses this
>particular bit of information could just as easily use the same context
>definition for any WDFOBJECT, I had the bright idea that I could use
>WdfObjectAllocateContext() to allocate that separate context blob, and
>everyone is happy. Except, I can't cleanup the small context I've
>allocated until I've cleaned up the default context first.
>
> Are there any guarantees on the order of context cleanup callbacks for a
> single object? Or do you only get one context cleanup for a WDFOBJECT,
> which would allow me to cleanup both contexts in the order I choose? What
> happens if I pass one EvtCleanupCallback in the WDF_OBJECT_ATTRIBUTES I
> use to setup the default context, and a different one in the attributes I
> pass to WdfObjectAllocateContext()?

---
NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
OSR Seminars – OSR

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum

Doron,

Thanks for the response. You've confirmed what I thought.

Could I request that you do commit to a contract, and further suggest that
if you do commit to a contract, that the cleanup order be LIFO, and the
default context be the last one, after all the allocated contexts? Other
schemes are certainly viable, but that one seems to be the most rational.
It would also seem to be rational to apply the same ordering to the
EvtDestroyCallback.

Based on the docs for both callbacks, for a single WDFOBJECT with multiple
contexts, it appears that all of the EvtCleanupCallback()s will be called
before any EvtDestroyCallback()s. Is that a correct interpretation?

The cleanup of all children before the parents is documented, and I have no
problem with there being no ordering guarantee between siblings, especially
if that is explicitly documented, although I didn't find it in the minute I
spent looking for that.

Thanks,

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Doron Holan" wrote in message
news:xxxxx@ntdev...
I just got back from being gone for a week. The order of cleanup on
contexts on one object is not currently defined, I am going to talk with the
team to see if we want to commit to documenting the ordering of the context
cleanup calls or not....and yes, you are right, the source would tell you
what happens, but you would get the same data empirically. The source would
not tell you if this is an explicit contract or not anyways, it just makes
function calls through function pointers ;).

Where the default context (where default is the context specified in the
WDF_OBJECT_ATTRIBUTES during the Create call or the context specified for
requests or file objects during device init) is also not documented (but
empirically you can see that it is always the first one), I will see if we
want to commit to ordering here as well.

And to be clear about ordering overall between different objects (vs your
question of different contexts on the same object), the only guarantee is
that all child objects of a parent object will be cleaned up before the
parent object's cleanup callback is called, there is intentionally no
ordering guarantee between siblings who share the same parent.

If we commit to a contract, it would be the current behavior which is FIFO, not LIFO. We cannot apply any contract to the EvtDestroyCallback(). Destroy() is called when the last reference is removed. Since the driver can do add/remove references at its own whim, creating an interdependency on ref counts would be overly complicated (to nearly impossible to get right). Cleanup() will always be called before Destroy(), that should be doc'ed somewhere.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Philip D. Barila
Sent: Monday, September 17, 2007 12:13 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Re:KMDF object context cleanup order

Doron,

Thanks for the response. You've confirmed what I thought.

Could I request that you do commit to a contract, and further suggest that
if you do commit to a contract, that the cleanup order be LIFO, and the
default context be the last one, after all the allocated contexts? Other
schemes are certainly viable, but that one seems to be the most rational.
It would also seem to be rational to apply the same ordering to the
EvtDestroyCallback.

Based on the docs for both callbacks, for a single WDFOBJECT with multiple
contexts, it appears that all of the EvtCleanupCallback()s will be called
before any EvtDestroyCallback()s. Is that a correct interpretation?

The cleanup of all children before the parents is documented, and I have no
problem with there being no ordering guarantee between siblings, especially
if that is explicitly documented, although I didn't find it in the minute I
spent looking for that.

Thanks,

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Doron Holan" wrote in message
news:xxxxx@ntdev...
I just got back from being gone for a week. The order of cleanup on
contexts on one object is not currently defined, I am going to talk with the
team to see if we want to commit to documenting the ordering of the context
cleanup calls or not....and yes, you are right, the source would tell you
what happens, but you would get the same data empirically. The source would
not tell you if this is an explicit contract or not anyways, it just makes
function calls through function pointers ;).

Where the default context (where default is the context specified in the
WDF_OBJECT_ATTRIBUTES during the Create call or the context specified for
requests or file objects during device init) is also not documented (but
empirically you can see that it is always the first one), I will see if we
want to commit to ordering here as well.

And to be clear about ordering overall between different objects (vs your
question of different contexts on the same object), the only guarantee is
that all child objects of a parent object will be cleaned up before the
parent object's cleanup callback is called, there is intentionally no
ordering guarantee between siblings who share the same parent.

---
NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
OSR Seminars – OSR

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum

OK, the refcount issues with trying to guarantee an order of
EvtDestroyCallback makes sense. The fact that *an* EvtCleanupCallback()
will be called before *an* EvtDestroyCallback() is clearly documented. All
the docs are just way too loose on multiple contexts, which is why I was
asking specifically about it.

I hope your commitment to FIFO isn't engraved in stone. If you were to
change it to LIFO, your users could guarantee teardown in the reverse order
of construction. That can be useful at times. Since the default context
(if configured) is present as soon as the WdfYYYCreate() returns, it's a
logical construct to cleanup/destroy it last. I'm not sure I can see a
similar benefit to the users of a FIFO implementation. Could you enlighten
me?

Since I seem to be the first one asking for it, I don't think anyone would
mind waiting for whatever next release you could get it into for you to make
the ordering guarantee public.

As always, thanks for the help,

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Doron Holan" wrote in message
news:xxxxx@ntdev...
If we commit to a contract, it would be the current behavior which is FIFO,
not LIFO. We cannot apply any contract to the EvtDestroyCallback().
Destroy() is called when the last reference is removed. Since the driver
can do add/remove references at its own whim, creating an interdependency on
ref counts would be overly complicated (to nearly impossible to get right).
Cleanup() will always be called before Destroy(), that should be doc'ed
somewhere.

So you can wait for the next public release before releasing your code? Or are you going to be working around this anyway?

I ask because you're not just the "first one" asking. At the moment you're the "only one" asking. Let's say we don't change the behavior until Windows 7. Because of this thread we'll have people who think they can take a dependency on FIFO cleanup regardless of whether we might make it LIFO in the future.

So now we have a change in behavior from undocumented but dependable to documented but dependably in the reverse order.

LIFO does make some sense, if you believe that having cross-dependencies between contexts is a good diea (something we clearly hadn't considered since we didn't guarantee any order). But it's very possibly too late, unless we give you a switch you can flip to get LIFO cleanup order in which case the complexity becomes worse.

And if you're already going to have worked around this in your driver then our current customer base of one has evaporated by that time.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Philip D. Barila
Sent: Monday, September 17, 2007 1:25 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Re:Re:KMDF object context cleanup order

OK, the refcount issues with trying to guarantee an order of
EvtDestroyCallback makes sense. The fact that *an* EvtCleanupCallback()
will be called before *an* EvtDestroyCallback() is clearly documented. All
the docs are just way too loose on multiple contexts, which is why I was
asking specifically about it.

I hope your commitment to FIFO isn't engraved in stone. If you were to
change it to LIFO, your users could guarantee teardown in the reverse order
of construction. That can be useful at times. Since the default context
(if configured) is present as soon as the WdfYYYCreate() returns, it's a
logical construct to cleanup/destroy it last. I'm not sure I can see a
similar benefit to the users of a FIFO implementation. Could you enlighten
me?

Since I seem to be the first one asking for it, I don't think anyone would
mind waiting for whatever next release you could get it into for you to make
the ordering guarantee public.

As always, thanks for the help,

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Doron Holan" wrote in message
news:xxxxx@ntdev...
If we commit to a contract, it would be the current behavior which is FIFO,
not LIFO. We cannot apply any contract to the EvtDestroyCallback().
Destroy() is called when the last reference is removed. Since the driver
can do add/remove references at its own whim, creating an interdependency on
ref counts would be overly complicated (to nearly impossible to get right).
Cleanup() will always be called before Destroy(), that should be doc'ed
somewhere.

---
NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
OSR Seminars – OSR

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum

I'm working around it. With only two object contexts, I can use the cleanup
callback in the allocated context, and the destroy callback in the default
one, and I *think* I'm safe. I don't like the uncertainty, but you've not
given me much choice.

Anyone *depending* on the "undocumented but dependable" behavior currently
in place deserves whatever headache they get out of it. I hope you will
unequivocally come out and say that we should *NOT* depend on the FIFO
ordering unless you document it to be so, and until such time, it is subject
to change with a hotfix, etc ...

I don't like having the cross-context dependency, but I'm stuck with it, and
the alternative is much, much worse. As you may remember from earlier
queries, this is a lab test harness, it's never going to be a shipping
product without really large changes to some of it to make it less
demanding. So I can take a few "liberties" that I would never do in a
production driver, such as pre-allocating huge amounts of contiguous memory
and other selfish things.

Thanks for the insight,

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Peter Wieland" wrote in message
news:xxxxx@ntdev...
So you can wait for the next public release before releasing your code? Or
are you going to be working around this anyway?

I ask because you're not just the "first one" asking. At the moment you're
the "only one" asking. Let's say we don't change the behavior until Windows
7. Because of this thread we'll have people who think they can take a
dependency on FIFO cleanup regardless of whether we might make it LIFO in
the future.

So now we have a change in behavior from undocumented but dependable to
documented but dependably in the reverse order.

LIFO does make some sense, if you believe that having cross-dependencies
between contexts is a good diea (something we clearly hadn't considered
since we didn't guarantee any order). But it's very possibly too late,
unless we give you a switch you can flip to get LIFO cleanup order in which
case the complexity becomes worse.

And if you're already going to have worked around this in your driver then
our current customer base of one has evaporated by that time.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Philip D. Barila
Sent: Monday, September 17, 2007 1:25 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Re:Re:KMDF object context cleanup order

OK, the refcount issues with trying to guarantee an order of
EvtDestroyCallback makes sense. The fact that an EvtCleanupCallback()
will be called before an EvtDestroyCallback() is clearly documented. All
the docs are just way too loose on multiple contexts, which is why I was
asking specifically about it.

I hope your commitment to FIFO isn't engraved in stone. If you were to
change it to LIFO, your users could guarantee teardown in the reverse order
of construction. That can be useful at times. Since the default context
(if configured) is present as soon as the WdfYYYCreate() returns, it's a
logical construct to cleanup/destroy it last. I'm not sure I can see a
similar benefit to the users of a FIFO implementation. Could you enlighten
me?

Since I seem to be the first one asking for it, I don't think anyone would
mind waiting for whatever next release you could get it into for you to make
the ordering guarantee public.

As always, thanks for the help,

Phil
--
Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Doron Holan" wrote in message
news:xxxxx@ntdev...
If we commit to a contract, it would be the current behavior which is FIFO,
not LIFO. We cannot apply any contract to the EvtDestroyCallback().
Destroy() is called when the last reference is removed. Since the driver
can do add/remove references at its own whim, creating an interdependency on
ref counts would be overly complicated (to nearly impossible to get right).
Cleanup() will always be called before Destroy(), that should be doc'ed
somewhere.

---
NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
OSR Seminars – OSR

To unsubscribe, visit the List Server section of OSR Online at
ListServer/Forum