Implicit IRP handling by WDF

I am maintaining WDF-based device drivers, and received a requirement from
a customer to comply with
a specific behavior when handling IRP_MN_START_DEVICE and
IRP_QUERY_DEVICE_RELATIONS.
This requirement appears (as a recommendation) in WDK documentation:

“On Windows Vista and later operating systems, we recommend that drivers
always pend the IRP_MN_START_DEVICE IRP
and complete its processing later. This order enables the system to
process device restarts asynchronously.
(On operating systems before Windows Vista, drivers can return
STATUS_PENDING from their dispatch routines,
but the PnP manager does not overlap the device restart with any other
operation.)”
“On Windows Vista and later operating systems, we recommend that drivers
always pend the IRP_MN_QUERY_DEVICE_RELATIONS IRP
and complete its processing later. This order enables the system to
process bus relation queries asynchronously.
(On operating systems before Windows Vista, drivers can return
STATUS_PENDING from their dispatch routines,
but the PnP manager does not overlap the bus relation query with any other
operation.)”

The problem is that these drivers do not handle IRPs directly at all,
since they rely on handling by WDF,
which as I understand is a combination of WDF default actions and calls to
PnP callbacks, some of which are
implemented in these drivers.

My question is - does WDF comply with the requirement above ?
Alternatively, is it correct to say that regarding
WDF-based drivers, the requirement is invalid ?

If the requirement is legitimate for WDF-based drivers as well - which
callbacks do I need to implement or modify
in order to comply ?

Thanks,
Galit

===========================================================================================
The privileged confidential information contained in this email is intended for use only by the addressees as indicated by the original sender of this email. If you are not the addressee indicated in this email or are not responsible for delivery of the email to such a person, please kindly reply to the sender indicating this fact and delete all copies of it from your computer and network server immediately. Your cooperation is highly appreciated. It is advised that any unauthorized use of confidential information of Winbond is strictly prohibited; and any information in this email irrelevant to the official business of Winbond shall be deemed as neither given nor endorsed by Winbond.

> My question is - does WDF comply with the requirement above ?

I think WDF violates this recommendation.


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

For start irps, yes, KMDF will pend the irp and process it asynchronously if you are the power policy owner (PPO) for the stack. If you are creating an FDO and not calling WdfDeviceInitSetFilter, you are the PPO.

QDR/BusRelations is a little more complicated of an answer. The short answer is that no, KMDF does not pend the IRP. BUT, there is no need to pend the IRP once you look at why this particular rule exists. It exists b/c it is very hard to manage the state of all of your PDOs individually and then coordinate that state with the QDR IRP along with any timers/DPCs/interrupts that may be associated with PDO state changes. By pending the irp and not blocking the IRP and waiting for all of these state changing inputs to coordinate, you do not block the OS…BUT, if all you did in the QDR was report the current state w/out blocking (or waiting for detection logic to finish), there is no need to pend the QDR irp. The WDFCHILDLIST manages the complex state of each PDO and does not block the QDR waiting for changes to complete, it just reports the current state of the list and returns. So in essence while it does not return STATUS_PENDING, KMDF will return the last committed state of the list to the pnp manager quickly, fulfilling the requirements that the OS has to return from QDR quickly.

You might ask yourself, what if the QDR comes in the middle of a scan and the WDFCHILDLIST reports the old state? Well, when the scan is complete,the WDFCHILDLIST will invalidate device relations and ask for a new QDR which will report the new state of the PDOs

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@winbond.com
Sent: Tuesday, April 01, 2008 4:47 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Implicit IRP handling by WDF

I am maintaining WDF-based device drivers, and received a requirement from
a customer to comply with
a specific behavior when handling IRP_MN_START_DEVICE and
IRP_QUERY_DEVICE_RELATIONS.
This requirement appears (as a recommendation) in WDK documentation:

“On Windows Vista and later operating systems, we recommend that drivers
always pend the IRP_MN_START_DEVICE IRP
and complete its processing later. This order enables the system to
process device restarts asynchronously.
(On operating systems before Windows Vista, drivers can return
STATUS_PENDING from their dispatch routines,
but the PnP manager does not overlap the device restart with any other
operation.)”
“On Windows Vista and later operating systems, we recommend that drivers
always pend the IRP_MN_QUERY_DEVICE_RELATIONS IRP
and complete its processing later. This order enables the system to
process bus relation queries asynchronously.
(On operating systems before Windows Vista, drivers can return
STATUS_PENDING from their dispatch routines,
but the PnP manager does not overlap the bus relation query with any other
operation.)”

The problem is that these drivers do not handle IRPs directly at all,
since they rely on handling by WDF,
which as I understand is a combination of WDF default actions and calls to
PnP callbacks, some of which are
implemented in these drivers.

My question is - does WDF comply with the requirement above ?
Alternatively, is it correct to say that regarding
WDF-based drivers, the requirement is invalid ?

If the requirement is legitimate for WDF-based drivers as well - which
callbacks do I need to implement or modify
in order to comply ?

Thanks,
Galit

===========================================================================================
The privileged confidential information contained in this email is intended for use only by the addressees as indicated by the original sender of this email. If you are not the addressee indicated in this email or are not responsible for delivery of the email to such a person, please kindly reply to the sender indicating this fact and delete all copies of it from your computer and network server immediately. Your cooperation is highly appreciated. It is advised that any unauthorized use of confidential information of Winbond is strictly prohibited; and any information in this email irrelevant to the official business of Winbond shall be deemed as neither given nor endorsed by Winbond.


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 WDFCHILDLIST manages the complex state of each PDO

and does not block the QDR waiting for changes to complete,
it just reports the current state of the list and returns.
So in essence while it does not return STATUS_PENDING, KMDF
will return the last committed state of the list to the pnp
manager quickly, fulfilling the requirements that the OS has
to return from QDR quickly.

That seems a little problematic if your boot storage device is on that bus.
My experience of writing a (non-KMDF) bus driver for bootable virtualized
storage devices is that if the boot device is not yet detected when the QDR
comes through, and you return an empty/incomplete list of devices, the OS
will continue sweeping up the PnP tree to build the initial devnodes. If it
then reaches a point that all QDR’s are complete and there is no bootable
disk, the OS will crash with inacessable boot device. My belief is QDR has
to essentially run synchronously at boot time, waiting for device detection.
Sometimes a worker thread might be required to figure out what pdo’s to put
on the bus, and that worker thread potentially has to do things like
establish communication with a remote management entity, which can take a
variable amount of time. Even for something like a fibre channel adapter,
the link may be up, but the remote name server is still detecting what
targets are on the fabric, so the driver must need to stall/pend the QDR
until it has a stable representation of what targets actually are online.
Imagine the situation just after power is restored to a FC boot server/FC
switch/FC RAID targets. There may be a little time period when the server
and FC switch are powered up, but the storage box has not yet presented the
targets to the fabric, so are not yet in the switch name server. The boot
disk is not really gone, it’s just not ready for use yet, and the FC storage
driver in the server will need to stall the QDR for a little while.

You might also want to boot from mirrored disks, on different (virtualized)
controllers. If QDR comes through at boot time, and finds only one of the
controller PDO’s, the volume manager may then declare the mirror broken, but
allow the boot to proceed. A few moments later, the second controller comes
online, and you find the system then initiates a mirror rebuild.

From what I’m reading in Doron’s message, an important feature of KMDF boot
device bus drivers might be a way to tell the framework if the WDFCHILDLIST
is logically valid or not, and for it to defer QDR irps until is is valid.

Jan

Well, there is no way to postpone the processing of a QDR. I know about the boot case, I chose not to originally mention this b/c it is a corner case. If you look at why returning STATUS_PENDING for a QDR was implemented in Vista, it was so that the pnp engine could async process a bunch of QDRs at once, speeding up the system. OTOH, the boot path requirements for QDR are the opposite, you /need/ to make sure that you find the boot volume before returning. It does not matter if you return STATUS_PENDING and do the work in a separate thread or if you search in the context of the QDR b/c w/out finding the boot volume, you do not even boot. So, with that said, while KMDF does not let you pend the QDR via a WDFCHILDLIST (which does not make much sense b/c you can have multiple WDFCHILDLISTs so it would really have to be a setting on the WDFDEVICE), you have the following options

a) register EvtDeviceSelfManagedIoInit and synchronously do the search for the boot volume.
b) register EvtDeviceRelationsQuery and track a little bit of state. the first time it is called, synchronously search for the boot volume, otherwise just return immediately
c) register EvtChildListScanForChildren and track a little bit of state. the first it is called, synchronously search, otherwise just return immediately
d) register a preprocess routine for IRP_MJ_PNP/IRP_MJ_QUERY_DEVICE_RELATIONS and track a little bit of state. the first time it is called, mark the irp as pending and in your worker thread synchronously search, otherwise just call WdfDeviceWdmDispatchPreprocessedIrp from the preprocess routine

if it were me, I would just pick a) since I do not have to track state, all I do is search, add the descriptions of found devices to the WDFCHILDLIST and return.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Jan Bottorff
Sent: Tuesday, April 01, 2008 5:28 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Implicit IRP handling by WDF

The WDFCHILDLIST manages the complex state of each PDO
and does not block the QDR waiting for changes to complete,
it just reports the current state of the list and returns.
So in essence while it does not return STATUS_PENDING, KMDF
will return the last committed state of the list to the pnp
manager quickly, fulfilling the requirements that the OS has
to return from QDR quickly.

That seems a little problematic if your boot storage device is on that bus.
My experience of writing a (non-KMDF) bus driver for bootable virtualized
storage devices is that if the boot device is not yet detected when the QDR
comes through, and you return an empty/incomplete list of devices, the OS
will continue sweeping up the PnP tree to build the initial devnodes. If it
then reaches a point that all QDR’s are complete and there is no bootable
disk, the OS will crash with inacessable boot device. My belief is QDR has
to essentially run synchronously at boot time, waiting for device detection.
Sometimes a worker thread might be required to figure out what pdo’s to put
on the bus, and that worker thread potentially has to do things like
establish communication with a remote management entity, which can take a
variable amount of time. Even for something like a fibre channel adapter,
the link may be up, but the remote name server is still detecting what
targets are on the fabric, so the driver must need to stall/pend the QDR
until it has a stable representation of what targets actually are online.
Imagine the situation just after power is restored to a FC boot server/FC
switch/FC RAID targets. There may be a little time period when the server
and FC switch are powered up, but the storage box has not yet presented the
targets to the fabric, so are not yet in the switch name server. The boot
disk is not really gone, it’s just not ready for use yet, and the FC storage
driver in the server will need to stall the QDR for a little while.

You might also want to boot from mirrored disks, on different (virtualized)
controllers. If QDR comes through at boot time, and finds only one of the
controller PDO’s, the volume manager may then declare the mirror broken, but
allow the boot to proceed. A few moments later, the second controller comes
online, and you find the system then initiates a mirror rebuild.

From what I’m reading in Doron’s message, an important feature of KMDF boot
device bus drivers might be a way to tell the framework if the WDFCHILDLIST
is logically valid or not, and for it to defer QDR irps until is is valid.

Jan


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

> then reaches a point that all QDR’s are complete and there is no bootable

disk, the OS will crash with inacessable boot device.

Sorry, what is “bootable disk” in this description? the volume device object
which has the ARC name which matches the BOOT.INI entry? this one?

My belief is QDR has
to essentially run synchronously at boot time, waiting for device detection.

Why? several QDRs can be sent in an async way, and then the OS can wait for all
of them (though pre-Vista this is never the case).

Vista+ async processing of QDR does not improve the time needed for your driver
to connect to SAN etc. Its only improvement is the ability for the OS to send
many QDRs in parallel.

So, the good idea for your driver is to do the SAN connect in a work item, and
then, when everything is ready, call IoInvalidateDeviceRelations, which will
force the OS to send QDR. The QDR path itself gets the array of your “PDO
descriptions”, creates the PDOs if necessary and returns relations to PnP.

KMDF streamlines this.


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

> So, the good idea for your driver is to do the SAN connect in

a work item, and then, when everything is ready, call
IoInvalidateDeviceRelations, which will force the OS to send
QDR. The QDR path itself gets the array of your “PDO
descriptions”, creates the PDOs if necessary and returns
relations to PnP.

That would not work, as the OS will send an initial QDR before you ever call
IoInvalidateDeviceRelations and if that list doesn’t include the bootable
device tree, it’s blue screen invalid boot device time. On pre-Vista, the
alternatives seem to be, if you can do the detect in the context of the QDR
thread, or else block the QDR thread and when a worker thread finishes
detection, unblock and return the pdo array.

Jan