Welcome to MSDN Blogs Sign in | Join | Help

Yes, No, Okay, Cancel!: I/O Cancellation in Windows

One of the leading causes of crashes for Microsoft Windows can be traced to device drivers that do not handle cancel requests properly, or at all. Cancellation is one of the most difficult concepts in driver technology to get right, and this blog entry will help clear up some of the confusion over cancellation.

What is Cancellation?

Device drivers sit between a user-mode software application and a hardware device. Sometimes the "device" can be software, such as named pipes or TCP/IP, and other times there may not be a user-mode application in the loop. The application sends data to the device, the device sends data back, and the driver sits in the middle, passing data back and forth. When the data transfers are done, the hardware signals the driver via an interrupt routine, the driver cleans up all I/O requests, and the close routine finishes up the job.

However, in a not-so-ideal universe, the data may not reach the user of the application quickly enough or the user may decide they don’t need the data after all, in which case the user decides to kill the application and then the system hangs. In many cases, the actual problem is that the driver doesn't handle the cancellation request properly, the hardware is malfunctioning, or something else has gone wrong … and the system hangs.

This is really all about IRPs, those hard-working I/O Request Packets that carry information around the system. When an I/O request is cancelled by an application or another driver, you must process that IRP. This sounds easy, but when your driver is part of a stack of drivers and you depend on hardware that may fail, or there are other things going on that slow down the IRP delivery, you need to think about all options. And cancellation requests are particularly difficult because there are several ways to handle cancellation.

Cancellation Options

There are a few different ways to think about cancellation. Since everything depends on what kind of application and what kind of hardware you are working with, the choice may not be simple.

  1. You can wait for a cancellation request to come in and try to figure out what to do. You have two basic choices at that point:

a.       Cut your losses and run. Just tell the hardware to stop, throw out the data, or whatever, and let the system shut the application and the communication to the device.

b.      Complete the operation if it is far enough along that it doesn’t need to wait anyway. If you are operating heavy machinery, you don't want to stop in the middle.

 

2.       See if your I/O requests are taking too long. In the past there weren’t any guidelines on how long a request should take. Paradoxically, as computers get faster, we ask them to do more, so how long a request takes may not be clear. If your driver proactively checks to see how long the requests are taking, you might discover important problems in the hardware, software, or your understanding of what the user will put up with. (People are more impatient now than they were five years ago!)

a.       One possibility is to set up a watchdog on the hardware to check after 30 seconds have elapsed. You might think of this as a warning and to perform further checks to see if the hardware is still plugged in, the network is slow, or whatever. The point of view of a device driver is limited to what it is told but you can look for more information if something might be going wrong.

b.      Another possibility is to decide after 5 minutes that something definitely isn’t working and shut things down. Most users won’t wait that long, but 5 minutes is a good drop-dead time.

3.       Do nothing. Not recommended. Apparently not everyone implements a Cancel routine in their driver. Microsoft doesn’t require it. Maybe your hardware is fast and never fails and you’ve got a secret deal with the scheduler. But you might want to think about it. The world is getting more complicated and that definitely applies to hardware and software.

Where’s My IRP, Dude?

Under some circumstances, the operating system or another driver may cancel the IRP your cancel routine registered. This can be a problem.

For example, in the Windows Driver Kit (WDK) Kernel-Mode Driver Architecture “Registering a Cancel Routine” topic, we tell you:

If a driver does not have a StartIo routine, its dispatch routines must do the following before queuing an IRP for further processing by other driver routines:

1.             Call IoAcquireCancelSpinLock.

2.             Call IoSetCancelRoutine with the input IRP and the entry point for a driver-supplied Cancel routine.

3.             Call IoReleaseCancelSpinLock.

This list sounds good, but if the IRP was already cancelled before the driver routine, you have a problem. There are various ways that an IRP can be cancelled before it gets to you; some of them are very subtle, and we will be covering them in future documentation.

What Can I Do About This?

Microsoft is working on two things in the near future:

1.       The documentation covering I/O Cancellation will be revised and we’ll tell you when it is fixed.

2.       We’ll provide a set of guidelines for cancellation so that your driver can be a good citizen in the increasingly crowded world of Windows.

But there are two major guidelines in place that you may or may not know about now.

Guideline 1:  Use the Windows Driver Foundation

If your hardware and software can fit the requirements, the Windows Driver Foundation can do a lot of the housekeeping, not only for I/O cancellation, but also for other difficult operations such as power management and Plug-and-Play. For more information about the Windows Driver Foundation, get started on WHDC and then dive into the WDK section on “Windows Driver Foundation.”

Guideline 2: Use Cancel-Safe Queues

Windows Vista has added a new technology called Cancel-Safe Queues. Cancel-safe IRP queues split IRP handling into two parts:

  1. The driver provides a set of callback routines that implement standard operations on the driver's IRP queue. The provided operations include inserting and removing IRPs from the queue, and locking and unlocking the queue.
  2. Whenever the driver needs to actually insert or remove an IRP from the queue, it uses the system-provided IoCsqXxx routines along with its callback routines (?). The system-provided routines handle all synchronization and IRP canceling logic for the driver.

Drivers that use cancel-safe IRP queues do not implement Cancel routines to support IRP cancellation. For more information about Cancel-Safe Queues, see the “Cancel-Safe IRP Queues” topic in the WDK Kernel-Mode Driver Architecture section.

For More Information

Stay tuned for more about I/O Cancellation!

Seth McEvoy [MSFT], WDK Technical Writer
http://blogs.msdn.com/wdkdocs    
This posting is provided "AS IS" with no warranties, and confers no rights.

Seth McEvoy is the kernel programmer writer for the Windows Driver Kit. He has worked on several operating systems at Microsoft and considers operating systems his favorite hobby.

Published Monday, June 30, 2008 3:51 PM by wdkblog

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# a-foton » Yes, No, Okay, Cancel!: I/O Cancellation in Windows

Monday, July 07, 2008 2:17 AM by jk

# re: Yes, No, Okay, Cancel!: I/O Cancellation in Windows

hi,

this is useful information so please keep it up

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker