Re: PreFast and NDISUIO

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Doron Holan [MS] (doronh_at_nospam.microsoft.com)
Date: 11/02/04


Date: Tue, 2 Nov 2004 08:15:17 -0800

b/c typically you acquire locks in a hierarchy. having not read the driver
sample code, it either does this
acqiure its own lock
acquire the cancel lock

or just

acuiqre its own lock

since the cancel routine is called with the cancel lock held, the order is
either reversed (which can cause a deadlock) or there is no need for the
cancel spinlock for any type of synchronization.

Also, when you mix the release of one lock after acquiring another, you have
to be very very careful about IRQL. In this case, if you were to acquire
your own lock before releasing the cancel spinlock , you must make sure the
previous IRQL is tracked properly, essentially something like this

KIRQL prevIrql;

prevIrql = Irp->CancelIrql;
IoReleaseCancelSpinLock(DISPATCH_LEVEL);

KeAcquireSpinLockAtDispatchLevel((&your spin lock);
// you could use KeAcquireSpinLock(&your spinLock, &dummyIrql), but you
would irgnore dummyIrql afterwards b/c it is not the IRQL you need to
restore to

do stuff with the canceled request...

KeReleaseSpinLock(&your spin lock, prevIrql);

As you can see, this is complicate. releasing the cancel spinlock
beforehand makes the code

KIRQL prevIrql;

IoReleaseCancelSpinLock(Irp->CancelIrql);

// must use this version, you don't know what IRQL you are at anymore after
releasing the prev lock
KeAcquireSpinLock(&your spin lock, &prevIrql);
do stuff()
KeReleaseSpinLock(&your lock, prevIrql);

d

-- 
Please do not send e-mail directly to this alias. this alias is for 
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
"Arne Ludwig" <arne@citde.net> wrote in message 
news:84bdcc66.0411020440.1ae6f1e5@posting.google.com...
>I apparently misinterpreted what PreFast said. I found this in a
> Microsoft document:
>
> The following notes refer to the circled numbers in the sample code:
> 1. Remove the IRP from the pending structure before releasing the
> cancel spin lock to prevent any other thread from trying to dequeue
> it.
> 2. Release the cancel spin lock. The I/O Manager acquires the cancel
> spin lock before it calls the Cancel routine; the Cancel routine must
> release the lock.
> 3. Complete the IRP. A driver must never call IoCompleteRequest while
> it holds the cancel spin lock.
>
> and in another Microsoft document:
>
> Calling IoCompleteRequest to complete an IRP constitutes a call
> outside the driver. A deadlock could occur in the system if your
> cancel routine completes the IRP while the kernel is holding the
> cancel spinlock for you. So the cancel routine has to release the
> global cancel spinlock first, then complete the cancelled IRP.
>
>
> However, the original question still stands (slightly modified):
>
> Why did Microsoft release the spinlock right at the beginning of the
> cancel routine instead of after releasing the local lock and before
> completing the IRP?
>
>
>
> arne@citde.net (Arne Ludwig) wrote in message 
> news:<84bdcc66.0411010055.49f5858b@posting.google.com>...
>> We modified the DDK NDISUIO driver and I ran PreFast with driver
>> enhancements from the Server 2003 Beta DDK on it. PreFast complained
>> about some original Microsoft code that releases the cancel spinlock
>> before the IRP was completed. I then moved the release down to after
>> the complete and the driver still seems to work, but I wonder why
>> Microsoft did it in the first place. Of course performancewise it is
>> always best to release the spinlock as soon as possible.
>>
>> Was it allowed in this particular case and PreFast was wrong? 


Relevant Pages

  • Re: PreFast and NDISUIO
    ... don't use teh cancel spinlock for enqueueing. ... Remove the IRP from the pending structure _before_ releasing the ... >> Also, when you mix the release of one lock after acquiring another, you ...
    (microsoft.public.win32.programmer.kernel)
  • Re: PreFast and NDISUIO
    ... don't use teh cancel spinlock for enqueueing. ... Remove the IRP from the pending structure _before_ releasing the ... your own lock before releasing the cancel spinlock, ...
    (microsoft.public.win32.programmer.kernel)
  • Re: IRP cancelation with IOM supplied device queue
    ... Another important role for the lock (cancel spinlock or your private lock) ... > Yes, in IOM queue, it's superflous. ...
    (microsoft.public.development.device.drivers)
  • Re: IRP cancelation with IOM supplied device queue
    ... > Another important role for the lock (cancel spinlock or your private lock) ... > private queuing, the synchronization for cancellation will be taken care ... in IOM queue implementation... ...
    (microsoft.public.development.device.drivers)
  • Re: Library design for canceling a running operation?
    ... cancel_create; ... That's going to require taking some lock. ... acquire some lock to check on the status of the worker thread, ... If you are choosing an atomic operation to avoid the overhead of a ...
    (comp.programming.threads)