Re: How to check if a spin lock has been freed or released?
- From: Bill Paul <wpaul@xxxxxxxxxxxxxxxx>
- Date: Thu, 26 Jan 2006 22:58:10 -0800
Barry <gubaoqiang@xxxxxxx> wrote:
> Hi, all,
>
> Since all the four functions NdisAcpuireSpinLock, NdisAllocateSpinLock,
> NdisReleaseSpinLock and NdisFreeSpinLock return VOID, how do I know if a
> spin lock has been freed or released in a NDIS protocol driver?
>
> In other words, what will happen if I call NdisAllocateSpinLock after
> NdisFreeSpinLock in DriverUnload routine? Cause a deadlock or BSOD? or maybe
> the driver could just run without any problem?
For the record, here is how the NDIS spinlock functions map to Windows
kernel spinlock functions:
NdisAllocateSpinLock() -> KeInitializeSpinLock() (initialize lock)
NdisAcquireSpinLock() -> KeAcquireSpinLock() (obtain lock)
NdisReleaseSpinLock() -> KeReleaseSpinLock() (release lock)
NdisFreeSpinLock() -> (nothing -- function is a no-op)
Now, a spinlock is really just an int. And all KeInitializeSpinLock()
does is set it to 0. In reality, NdisAllocateSpinLock() does not allocate
anything. It's up to you to allocate storage for the NDIS_SPIN_LOCK,
and all NdisAllocateSpinLock() does is initialize the structure. And
NdisFreeSpinLock() doesn't do anything.
So, even though it's an incorrect use of the API, you can technically
call NdisFreeSpinLock() any time you like, and it won't have any effect
at all. How do I know this? Because when I implemented the NDIS emulator
for FreeBSD, I struggled for a while to come up with a spinlock
implementation that duplicated the semantics of Windows spinlocks
(without conflicting with FreeBSD's own locking primitives), and I ran
across at least one driver that called NdisFreeSpinLock() incorrectly.
The driver for the ADMtek 802.11b chipset (which was rebadged and sold
by 3Com for a while) would do the following in its MiniportHalt()
handler:
NdisFreeMemory(pAdapter);
NdisFreeSpinLock(pAdapter->mySpinLock);
This is bogus: pAdapter has already been released, so all members of the
pAdapter structure are now invalid, including the spinlock storage. This
is technically a 'touch-after-free' bug. But because NdisFreeSpinLock()
is a no-op in Windows, the bug ends up having no effect. In fact, I suspect
the Microsoft NDIS tester doesn't catch this error (otherwise it would
have shown up before ADMtek released the driver).
At the time, my implementation of NdisFreeSpinLock() actually touched the
spinlock that was passed to it, so in FreeBSD, if you ran a development
kernel with debugging enabled and loaded the ADMtek driver, you'd get a
trap as soon as the MiniportHalt() routine was called. Eventually I
created a spinlock implementation that imitated Windows closely enough
that I could make NdisFreeSpinLock() into a no-op just like it is in
Windows.
So if NdisFreeSpinLock() doesn't do anything, why is it there? To fill
out the API in case someone implements NDIS on an OS where the locking
primitives are different.
In any case, you can mistakenly call NdisFreeSpinLock() any time you
want and it won't break anything. If you call NdisAllocateSpinLock()
at the wrong time, you can break things: it will reset the spinlock
to 0 regardless if someone's already holding it. If you call
NdisAcquireSpinLock() twice in the same thread, the thread will deadlock.
-Bill
--
=============================================================================
-Bill Paul (510) 749-2329 | Senior Engineer, Master of Unix-Fu
wpaul@xxxxxxxxxxxxxxxxxxxxx | Wind River Systems
=============================================================================
<adamw> you're just BEGGING to face the moose
=============================================================================
.
- Follow-Ups:
- Re: How to check if a spin lock has been freed or released?
- From: Stephan Wolf [MVP]
- Re: How to check if a spin lock has been freed or released?
- From: Barry
- Re: How to check if a spin lock has been freed or released?
- References:
- Prev by Date: Re: Q) Disabling IO port space during it's installation time.
- Next by Date: Problem with usb driver
- Previous by thread: Re: How to check if a spin lock has been freed or released?
- Next by thread: Re: How to check if a spin lock has been freed or released?
- Index(es):
Relevant Pages
|