Generally, to avoid deadlock situations, it is considered best practice to
release locks in the inverse order they were acquired. It has been 40 years
since we had to do the formal proof for this, so I no longer recall all the
details. But I have this bit set that says “unlock in inverse order”.
joe
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Mark Roddy
Sent: Wednesday, August 25, 2010 10:54 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] releasing a spinlock when not at dispatch level
I’ll simplify the problem:
//
// always called at DISPATCH_LEVEL
//
foo()
{
KeAcquireSpinLockAtDpcLevel(&spinlock1);
KeAcquireSpinLockAtDpcLevel(&spinlock2);
stuffRequiringLock1andLock2();
KeReleaseSpinLockFromDpcLevel(&spinlock1);
stuffRequiringLock2();
KeReleaseSpinLockFromDpcLevel(&spinlock2);
}
ok - now that IRQL is out of the picture, what exactly is the problem?
Mark Roddy
On Wed, Aug 25, 2010 at 10:46 AM, Mark Roddy wrote:
The correct IRQL is maintained entirely by the dispatch spinlock user which
is why KeAcquireSpinLockAtDpcLevel can exist. Yes I understand what the docs
say. And as I have said repeatedly, you do have to maintain the IRQL state
correctly, but what does that actually mean?
I am claiming that it means this:
In a sequence of dispatch spinlock acquisitions, the first acquire sets the
IRQL state from <= DISPATCH_LEVEL to DISPATCH_LEVEL and saves the initial
IRQL state. The last release restores the IRQL level from DISPATCH_LEVEL to
the saved IRQL state. The optimization KeAcquireSpinLockAtDpcLevel exists
because the client, the user of spinlocks, knows the IRQL state I just
described and can make an informed decision at acquire time regarding which
form of acquire to use.
There is no functional requirement to do the release of the locks in any
specific order. Docs and prefast may differ. This isn’t an implementation
detail it is fundamental to dispatch spinlocks. You cannot cause a spinlock
deadlock on lock release, but you do have to maintain the IRQL correctly.
Mark Roddy
On Wed, Aug 25, 2010 at 12:34 AM, James Harper
wrote:
>
> As I said - you have to maintain irql correctly, but that does not
require
> release ordering.
>
> KIRQL originalIrql;
>
> KeAcquireSpinLock(&spinlock1, &originalIrql);
> KeAcquireSpinLockAtDpcLevel(&spinlock2);
>
> … do some stuff
>
> KeReleaseSpinLockFromDpcLevel(&spinlock1);
>
> … do some more stuff
>
> KeReleaseSpinLock(&spinlock2, originalIrql);
>
> What violation of anything other than our affinity for symmetry
happened?
>
A violation of the rules. You are doing exactly what the docs say not to
do. From KeReleaseSpinLockFromDpcLevel:
“
It is an error to call KeReleaseSpinLockFromDpcLevel if the given spin
lock was acquired by calling KeAcquireSpinLock because the caller’s
original IRQL is not restored, which can cause deadlocks or fatal page
faults.
”
And from KeReleaseSpinLock:
“
VOID
KeReleaseSpinLock(
IN PKSPIN_LOCK SpinLock,
IN KIRQL NewIrql
);
NewIrql
Specifies the IRQL value saved from the preceding call to
KeAcquireSpinLock.
”
Now I know and you know that the current implementation of those
functions means that what you have done above gives the correct result,
and it’s probably reasonable to assume that it will never cause a
problem in any future version of Windows, but it’s a violation of the
contract and therefore should be frowned upon unless there is a very
good reason for doing it. I’d like to see a legitimate reason for
releasing the locks in any order than the reverse of the order in which
they were acquired.
Many regressions are caused by people thinking they can violate the
rules because they know how it works and know they will get the correct
result, even if the rules appear dumb.
James
—
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
— 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 message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.