Hi,
I am running Driver Verifier tests (Forced IRQL Enabled) on the kernel mode
protocol driver on a multiprocessor machine.
The following errors are seen:
-
KeBugCheck, C4 with P1=33 occurs which says that "The driver attempted to
acquire fast mutex at an IRQL above APC_LEVEL. "
The code it shows accessing this mutex is a thread created by our driver
which runs in a continuous mode
with sleep for a few milliseconds. In the driver, I am not raising the IRQL
of the system.
-
KeBugCheck, C4 with P1=3B occurs which says that "The driver called
KeWaitXxx at an IRQL of DISPATCH_LEVEL or higher.
(This is permitted only if the driver already owns the DISPATCHER lock and
it passes a timeout value of zero to the routine.) "
Here the driver code is acquiring a mutex using the call,
KeWaitForMutexObject with timeout parameter set to NULL.
Seeing the above issues, I have the following question:
- How should I handle the calls to the Mutex Objects for the piece of code
that gets scheduled at DISPATCH_LEVEL?
Do I really need to say for all calls to mutex objects something like below:
If (CurrentIrql == DISPATCH_LEVEL)
Donot acquire/wait for Mutex;
Acquire Spin Lock; //This is for multi-processor machine
Set Mutex/Spin Lock flag as true;
Else
Acquire Mutex;
<<<>>>>>
Release Mutext/Spin Lock on the basis of flag;
In the code sample given above, How can I write a generic piece of code that
releases Mutex safely, taking the
above scenario of DISPATCH_LEVEL into account? Is this a valid approach?
3. Going by the DDK Documentation, both Mutex and Spin Lock can be used at
Dispatch Level. If this is the case,
then why do we see bugcheck while trying to wait for mutex with timeout set
to NULL? Is this incorrect?
2. What causes the kernel threads in the driver run at DISPATCH_LEVEL? What
shall be the approach to handle
functions like accessing Paged Memory or Synchronization objects if the
driver is executed at Dispatch Level?
If anybody thinks crash dump of the above scenarios will help, Pls let me
know. Any insights into the above problems will
be of great help !
Appreciate your response,
Arvind.
For code running at DISPATCH_LEVEL you need to use spinlocks. Your sample
code has the problem, of processor 1 acquires the spinlock, process 2
acquires the mutex, they run at the same time and trash the data being
protected!
You cannot wait to acquire a mutex at DISPATCH_LEVEL so trying to use a
mutex for code that can be running at that level is a bad idea.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply
“Arvind” wrote in message
news:xxxxx@ntdev…
> Hi,
> I am running Driver Verifier tests (Forced IRQL Enabled) on the kernel
> mode
> protocol driver on a multiprocessor machine.
> The following errors are seen:
>
> 1. KeBugCheck, C4 with P1=33 occurs which says that "The driver attempted
> to
> acquire fast mutex at an IRQL above APC_LEVEL. "
> The code it shows accessing this mutex is a thread created by our driver
> which runs in a continuous mode
> with sleep for a few milliseconds. In the driver, I am not raising the
> IRQL
> of the system.
>
> 2. KeBugCheck, C4 with P1=3B occurs which says that "The driver called
> KeWaitXxx at an IRQL of DISPATCH_LEVEL or higher.
> (This is permitted only if the driver already owns the DISPATCHER lock and
> it passes a timeout value of zero to the routine.) "
> Here the driver code is acquiring a mutex using the call,
> KeWaitForMutexObject with timeout parameter set to NULL.
>
> Seeing the above issues, I have the following question:
> 1. How should I handle the calls to the Mutex Objects for the piece of
> code
> that gets scheduled at DISPATCH_LEVEL?
> Do I really need to say for all calls to mutex objects something like
> below:
>
> If (CurrentIrql == DISPATCH_LEVEL)
> Donot acquire/wait for Mutex;
> Acquire Spin Lock; //This is for multi-processor machine
> Set Mutex/Spin Lock flag as true;
> Else
> Acquire Mutex;
> <<<>>>>>
> Release Mutext/Spin Lock on the basis of flag;
>
> In the code sample given above, How can I write a generic piece of code
> that
> releases Mutex safely, taking the
> above scenario of DISPATCH_LEVEL into account? Is this a valid approach?
>
> 3. Going by the DDK Documentation, both Mutex and Spin Lock can be used at
> Dispatch Level. If this is the case,
> then why do we see bugcheck while trying to wait for mutex with timeout
> set
> to NULL? Is this incorrect?
>
> 2. What causes the kernel threads in the driver run at DISPATCH_LEVEL?
> What
> shall be the approach to handle
> functions like accessing Paged Memory or Synchronization objects if the
> driver is executed at Dispatch Level?
>
> If anybody thinks crash dump of the above scenarios will help, Pls let me
> know. Any insights into the above problems will
> be of great help !
> Appreciate your response,
> Arvind.
>
>
> 1. How should I handle the calls to the Mutex Objects for the piece of code
that gets scheduled at DISPATCH_LEVEL?
You cannot. Use spinlocks instead.
If (CurrentIrql == DISPATCH_LEVEL)
No, you must know what your routines run on DISPATCH_LEVEL and what below. This
is a design decision.
- Going by the DDK Documentation, both Mutex and Spin Lock can be used
at
Dispatch Level. If this is the case,
No. Spinlocks only.
- What causes the kernel threads in the driver run at DISPATCH_LEVEL?
Some of the driver’s functions are called by the OS at DISPATCH_LEVEL. IO
completion routines, for instance.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com