SDV, DrvAckIoStop, and __analysis_assume


With its integration into the Win8 WDK, I’ve been running SDV quite a bit on my drivers. I can honestly say that it’s found one or two problems… when it doesn’t accvio. But that’s not why I’m posting here.

My KMDF driver was accused of being a violator of the DrvAckIoStop rule… which apparently means “Your driver could have a Request that was presented by a power managed Queue in progress when your device wants to leave D0, and you don’t have an EvtIoStop or anything to deal with this.” I’m obviously retarded, because it took me about an hour to figure this out. I thought maybe SDV was trying to teach me some deep, dark, subtlety of KMDF power managed Queues that was previously unknown to me.

But I just think SDV is saying “You have a Queue presented request that you keep in progress and that could thus delay a remove/shutdown/sleep, cuz I don’t see a EvtIoStop.”

And, no… as far as I can tell, this delay isn’t actually possible in my driver. If I’ve got a Request in progress, it’s sitting in a Queue with manual dispatching, where it’s cancelable. I’m good with keeping the Request in progress on that Queue during an ordinary sleep/wake transition, where it will be processed some time after the device wakes back up. So, you know, no EvtIoStop needed.

I’m not complaining about the error, the description, the hour it took me to figure out what the issue is, or even the false warning. I appreciate SDV making me think through the issue. Sort of.

Now… All I want to do is suppress the warning that SDV’s giving me.

The SDV docs tell me to use __analysis_assume to do this. But I have no clue what to tell Analysis to Assume. What I want to say is “Analysis, please assume that I’m all good with pending Requests around my transitions out of D0. So, you know, you can stop telling me I’m a Gxd Cursed DvrAckIoStop violator… because I’m not one.”

In short, how do I suppress the SDV warning DrvAckIoStop?

Thanks for whatever info,

Peter
OSR

SOLVED!

One should always search the WDK Examples…

From S5933DK1.C:

Soooo… never mind. I hope you at least found my question semi-entertaining.

Kudos to whoever took the time to update the WDK samples to pass SDV 100% clean, by the way. Nice work.

Peter
OSR

Thanks! I’m told that it was a joint effort between the doc team and the dev team.

Those responsible have been alerted to your email thread. :slight_smile:

–Diane

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Tuesday, November 27, 2012 2:16 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SDV, DrvAckIoStop, and __analysis_assume

SOLVED!

One should always search the WDK Examples…

From S5933DK1.C:

[quote]
//
// By default, Static Driver Verifier (SDV) displays a warning if it
// doesn’t find the EvtIoStop callback on a power-managed queue.
// The ‘assume’ below causes SDV to suppress this warning. If the driver
// has not explicitly set PowerManaged to WdfFalse, the framework creates
// power-managed queues when the device is not a filter driver. Normally
// the EvtIoStop is required for power-managed queues, but for this driver
// it is not needed b/c the driver doesn’t hold on to the requests for
// long time or forward them to other drivers.
// If the EvtIoStop callback is not implemented, the framework waits for
// all driver-owned requests to be done before moving in the Dx/sleep
// states or before removing the device, which is the correct behavior
// for this type of driver. If the requests were taking an indeterminate
// amount of time to complete, or if the driver forwarded the requests
// to a lower driver/another stack, the queue should have an
// EvtIoStop/EvtIoResume.
//
__analysis_assume(ioQueueConfig.EvtIoStop != 0); [/quote]

Soooo… never mind. I hope you at least found my question semi-entertaining.

Kudos to whoever took the time to update the WDK samples to pass SDV 100% clean, by the way. Nice work.

Peter
OSR


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

The reason behind the rule (ignoring the warning text for now) is that we see a huge number of 9f bugchecks in kmdf due to being stuck waiting for a power managed queue to drain during power down. When looking at the pattern, we came to the conclusion that pretty much every power managed queue needed a stop ack routine so that disable and power down scenarios completed without blocking (obviously there are outlier cases). So I would recommend that while you think you don’t need the callback, go back and reevaluate what could go wrong in the edge cases.

d

dent from pjone


From: xxxxx@osr.commailto:xxxxx
Sent: ?11/?27/?2012 2:17 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] SDV, DrvAckIoStop, and __analysis_assume

SOLVED!

One should always search the WDK Examples…

From S5933DK1.C:



Soooo… never mind. I hope you at least found my question semi-entertaining.

Kudos to whoever took the time to update the WDK samples to pass SDV 100% clean, by the way. Nice work.

Peter
OSR


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</mailto:xxxxx></mailto:xxxxx>

OK, so I’m back to being retarded. I guess. Because I don’t see it.

The implementation pattern I’m using, one of my favorites by the way, has in-progress Requests being stored on a manual Queue. It’s a very simple, and very flexible, design pattern.

So, I’m presented with a Request from my “top edge” Queue… I take that Request, and “pend” it by forwarding it to my manual Queue of in-progress Requests. It hangs out there, happily, until my device does something interesting that will cause me to complete the Request.

My device hardware is happy to transition D0->Dx->D0 and have the Request remain in progress.

During D0->Dx nothing’s blocking either Queue from stopping, and thus the device power’s down.

For Unload, open handles need to be closed, so the pending Requests are canceled.

What “edge cases” am I missing?

While I appreciate you leaving the exercise to the reader, your comment leaves me uncertain if I’m overlooking something obvious, there’s some clever edge condition that I don’t see, or I’m not overlooking anything and this rule is complaining about something that’s not a problem in my case.

Another clue, please?

Peter
OSR

The manual queue is power managed or not? I have to go back and look to see if a power managed manual queue will block power down until everything is drained or ack’ed

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Tuesday, November 27, 2012 8:25 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SDV, DrvAckIoStop, and __analysis_assume

OK, so I’m back to being retarded. I guess. Because I don’t see it.

The implementation pattern I’m using, one of my favorites by the way, has in-progress Requests being stored on a manual Queue. It’s a very simple, and very flexible, design pattern.

So, I’m presented with a Request from my “top edge” Queue… I take that Request, and “pend” it by forwarding it to my manual Queue of in-progress Requests. It hangs out there, happily, until my device does something interesting that will cause me to complete the Request.

My device hardware is happy to transition D0->Dx->D0 and have the Request remain in progress.

During D0->Dx nothing’s blocking either Queue from stopping, and thus the device power’s down.

For Unload, open handles need to be closed, so the pending Requests are canceled.

What “edge cases” am I missing?

While I appreciate you leaving the exercise to the reader, your comment leaves me uncertain if I’m overlooking something obvious, there’s some clever edge condition that I don’t see, or I’m not overlooking anything and this rule is complaining about something that’s not a problem in my case.

Another clue, please?

Peter
OSR


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

The manual Queue is power managed. Well, PowerManaged in the Queue Config is allowed to default, to be very specific.

I can definitely transition the system D0->Dx with a Request on the Manual Queue.

In fact, I can do the D0->Dx transition with Requests on BOTH Queues (the manual Queue and a “top edge” Queue with Sequential dispatching, that has previously been STOPPED by the driver). I’ve tested this repeatedly.

You’re not saying you need to DRAIN Queues before going to Dx, right? That would be evil. You just can’t have Requests in PROGRESS (in the driver, NOT on a Queue) from either of these Queues before the Queues can be stopped, right?

Peter
OSR

Active Requests on a started queue need to be ack’ed in flight or drained/completed. All requests put onto the queue after the transition that were not presented to the driver are pended until power up. By stopping the queue, you effectively skip the logic of needing to ack in flight requests

d

dent from pjone


From: xxxxx@osr.commailto:xxxxx
Sent: ?11/?27/?2012 9:25 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] SDV, DrvAckIoStop, and __analysis_assume



The manual Queue is power managed. Well, PowerManaged in the Queue Config is allowed to default, to be very specific.

I can definitely transition the system D0->Dx with a Request on the Manual Queue.

In fact, I can do the D0->Dx transition with Requests on BOTH Queues (the manual Queue and a “top edge” Queue with Sequential dispatching, that has previously been STOPPED by the driver). I’ve tested this repeatedly.

You’re not saying you need to DRAIN Queues before going to Dx, right? That would be evil. You just can’t have Requests in PROGRESS (in the driver, NOT on a Queue) from either of these Queues before the Queues can be stopped, right?

Peter
OSR


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</mailto:xxxxx></mailto:xxxxx>

The point is: I don’t *have* any in-flight Requests OR any requests held pending in the driver, which is why SDV confused me with its warning (and made me wonder if I was missing some bigger point).

In my driver, Requests are either on the top-edge Queue (and not yet Presented), or they’re on the in-progress (manual) Queue.

But, what my personal driver does aside: I’m not trying to split hairs here, or argue. I’m trying to be certain we’re on the same page and that I’m STILL not missing some subtle hidden truth.

The way I understand it is:

I) Before a device can transition to Dx, its power managed Queues must be stopped.

II) Before a power managed Queue can be stopped, any Requests that have been presented from that Queue, but not yet completed by the driver, must be “accounted for.” You can “account for” each these Requests by:

a) Completing it in a timely manner
b) Successfully sending it to an I/O Target using Send And Forget
c) Forwarding it to another Queue
d) Registering an EvtIoStop event processing callback that
does one of the following:

  1. re-queues the Request if it currently owned by the driver, by calling
    WdfRequestStopAcknowledge with Requeue set to TRUE
  2. holds the Request in progress by calling WdfRequestStopAcknowledge
    with Requeue set to FALSE
  3. complete the Request (with whatever status makes sense)
  4. successfully cancel the Request by calling WdfRequestCancelSentRequest
    if the Request has been previous sent to an I/O Target without using
    Send And Forget
  5. Successfully send the Request to an I/O Target using Send And Forget
  6. Forward the Request to another Queue

Granted 5 and 6 above are unusual possibilities, but I think they’re technically valid… is that right?

And I *think* that’s the entire universe of correct possibilities? Am I wrong?

By the way… The WDK docs on this could use some work. The best description of all this that I was able to find is buried in the Remarks section for the WdfRequestStopAcknowledge function. The writing there is actually quite clear, and this should be pulled-out and put in a higher-level description of EvtIoStop. The example, however, strikes me as silly (at best) and potentially misleading (at worst).

On the meta-issue: I agree that EvtIoStop is probably poorly understood and hence under utilized. I know we don’t talk about it much, if at all, in our KMDF seminars. I think I’ll add some discussion on this topic.

Peter
OSR

xxxxx@osr.com wrote:

On the meta-issue: I agree that EvtIoStop is probably poorly understood and hence under utilized. I know we don’t talk about it much, if at all, in our KMDF seminars.

Yes, every time Doron talks about power management, I feel stupid again.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Agreed we haven’t done a good job getting the information out of our hallways and into the wild

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Wednesday, November 28, 2012 9:35 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SDV, DrvAckIoStop, and __analysis_assume

The point is: I don’t *have* any in-flight Requests OR any requests held pending in the driver, which is why SDV confused me with its warning (and made me wonder if I was missing some bigger point).

In my driver, Requests are either on the top-edge Queue (and not yet Presented), or they’re on the in-progress (manual) Queue.

But, what my personal driver does aside: I’m not trying to split hairs here, or argue. I’m trying to be certain we’re on the same page and that I’m STILL not missing some subtle hidden truth.

The way I understand it is:

I) Before a device can transition to Dx, its power managed Queues must be stopped.

II) Before a power managed Queue can be stopped, any Requests that have been presented from that Queue, but not yet completed by the driver, must be “accounted for.” You can “account for” each these Requests by:

a) Completing it in a timely manner
b) Successfully sending it to an I/O Target using Send And Forget
c) Forwarding it to another Queue
d) Registering an EvtIoStop event processing callback that
does one of the following:

  1. re-queues the Request if it currently owned by the driver, by calling
    WdfRequestStopAcknowledge with Requeue set to TRUE
  2. holds the Request in progress by calling WdfRequestStopAcknowledge
    with Requeue set to FALSE
  3. complete the Request (with whatever status makes sense)
  4. successfully cancel the Request by calling WdfRequestCancelSentRequest
    if the Request has been previous sent to an I/O Target without using
    Send And Forget
  5. Successfully send the Request to an I/O Target using Send And Forget
  6. Forward the Request to another Queue

Granted 5 and 6 above are unusual possibilities, but I think they’re technically valid… is that right?

And I *think* that’s the entire universe of correct possibilities? Am I wrong?

By the way… The WDK docs on this could use some work. The best description of all this that I was able to find is buried in the Remarks section for the WdfRequestStopAcknowledge function. The writing there is actually quite clear, and this should be pulled-out and put in a higher-level description of EvtIoStop. The example, however, strikes me as silly (at best) and potentially misleading (at worst).

On the meta-issue: I agree that EvtIoStop is probably poorly understood and hence under utilized. I know we don’t talk about it much, if at all, in our KMDF seminars. I think I’ll add some discussion on this topic.

Peter
OSR


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

This sounds like a job for… THE NT INSIDER!!

Peter
OSR

Peter wrote:


a) Completing it in a timely manner
b) Successfully sending it to an I/O Target using Send And Forget
c) Forwarding it to another Queue
d) Registering an EvtIoStop event processing callback that
does one of the following:
1) re-queues the Request if it currently owned by the driver, by calling
WdfRequestStopAcknowledge with Requeue set to TRUE
2) holds the Request in progress by calling WdfRequestStopAcknowledge
with Requeue set to FALSE
3) complete the Request (with whatever status makes sense)
4) successfully cancel the Request by calling WdfRequestCancelSentRequest
if the Request has been previous sent to an I/O Target without using
Send And Forget
5) Successfully send the Request to an I/O Target using Send And Forget
6) Forward the Request to another Queue


Just a clarification: keep in mind that the thread doing a, b, c, 1, 3, 4, 5 or 6 must have ownership of the request. The EvtIoStop callback doesn’t automatically give you ownership of the specified request.

Egi.

Ops, remove 4 from that list.

Just a clarification: keep in mind that the thread doing a, b, c, 1, 3, 5 or
6 must have ownership of the request. The EvtIoStop callback doesn’t
automatically give you ownership of the specified request.

Egi… Thanks VERY much for taking the time to read that list, think about it, and respond. I appreciate it, as I’m sure do other folks in the community.

Sorry to say, I *do* have a couple of follow-up questions:

  • You said “Remove 4 from that list”, which is the option to cancel a sent Request by calling WdfRequestCancelSentRequest. So that means that is NOT a valid thing to do. Would you please explain why, because it sounds reasonable to me.

The docs (see http:) seem to suggest this IS a valid option, as well:


If the driver has forwarded the I/O request to an I/O target, it can call WdfRequestCancelSentRequest to attempt to cancel the request.


- Your clarifying note says the driver “must have ownership of the Request.” Absolutely right, of course. The only time I can think of when you’d be called at EvtIoStop if you do NOT have ownership of the Request, is if you’ve sent it to an I/O Target without Send And Forget. Is there another case that I’m not seeing?

Again, thank you SOOO much for taking the time to read and respond. I seriously do appreciate it.

Peter
OSR</http:>

I assume Egi will respond and clarify, but I took the statement “Ops, remove 4 from that list.”, as referring to Egi’s list, which was originally:
“keep in mind that the thread doing a, b, c, 1, 3, 4, 5 or 6 must have ownership of the request”
but then became:
“keep in mind that the thread doing a, b, c, 1, 3, 5 or 6 must have ownership of the request”

Which makes sense, because it seems like you *don’t* own the request you’ve “sent to an I/O Target without using Send And Forget”.

Phil
Not speaking for LogRhythm

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Thursday, November 29, 2012 2:30 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SDV, DrvAckIoStop, and __analysis_assume

Egi… Thanks VERY much for taking the time to read that list, think about it, and respond. I appreciate it, as I’m sure do other folks in the community.

Sorry to say, I *do* have a couple of follow-up questions:

  • You said “Remove 4 from that list”, which is the option to cancel a sent Request by calling WdfRequestCancelSentRequest. So that means that is NOT a valid thing to do. Would you please explain why, because it sounds reasonable to me.

The docs (see http:) seem to suggest this IS a valid option, as well:


If the driver has forwarded the I/O request to an I/O target, it can call WdfRequestCancelSentRequest to attempt to cancel the request.


- Your clarifying note says the driver “must have ownership of the Request.” Absolutely right, of course. The only time I can think of when you’d be called at EvtIoStop if you do NOT have ownership of the Request, is if you’ve sent it to an I/O Target without Send And Forget. Is there another case that I’m not seeing?

Again, thank you SOOO much for taking the time to read and respond. I seriously do appreciate it.

Peter
OSR


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</http:>

AH, of course… THANK you Phil. I see MUST be exactly what he meant. He even restated his paragraph with the correction.

Duh!

(Sorry for being retarded, Egi!)

That DOES leave my second question, however. To wit:

Peter
OSR

Yes, the correct list is “a, b, c, 1, 3, 5 or 6”. Sorry about the ‘4’ I had in there before.

About the other question:
Yes, the requests are driver owned. But this is not what I’m referring it here. Your driver may use different concurrent threads, for example, it may be possible for your driver to process the request R1 on thread T1 (work-item or queue’s dispatcher’s thread) when framework invokes your EvtIoStop routine in the context of thread T2. In this case, it is up to your driver to provide the needed serialization between your threads T1 and T2 to do 1, 3, 5 or 6.

Egi.

Ah, yes. Certainly. Just like any other potentially shared chunk of data. EvtIoStop can’t possibly know if you’ve got the Request off being processed simultaneously “somewhere else”

Thanks very much for the clarification. It certainly is appreciated.

Peter
OSR