No that’s not right - you’ve confused several elements.
We’re talking about four different things here: DPCs, IRQL (including
DISPATCH_LEVEL), threads, and interrupts.
A DPC is a “deferred proceedure call” that you can enqueue to run on a
processor that will interrupt the processor when it’s IRQL is below
DISPATCH_LEVEL, but it is not the same thing as DISPATCH_LEVEL. DPCs
are NOT threads.
IRQL is the interrupt level at which the processor is running.
PASSIVE_LEVEL is the lowest level and is where processors spend most of
their life, running code from various threads of execution.
DISPATCH_LEVEL is a higher interrupt level, and a processor running at
DISPATCH_LEVEL does no scheduling. A processor can reach DISPATCH_LEVEL
in one of two ways - the running thread can be interrupted with a DPC,
or the running thread can call KeRaiseIrql to change the IRQL.
A thread is a persistent unit of execution. A thread can be suspended,
moved to another processor, or rescheduled if another higher priority
thread needs to run. The kernel decides what thread should be running
on each processor at any given time. That thread will run until it
deliberately yields the processor (say by waiting on a dispatcher
object), or until a timer interrupt decides that something else should
run.
Which brings us nicely to interrupts. Threads are one way a processor
is directed to run code. Interrupts are another (perhaps the other).
There are two types of interrupts. The first are hardware interrupts,
the interrupts you’re used to that come from devices. The second type
are software interrupts, interrupts sent by the kernel or HAL in order
to interrupt a processor and direct it to run some other code for a
little while - something like a DPC routine.
Let’s look at some examples:
Processor A has thread T running on it. Procesor B enqueues a DPC which
the kernel decides to run on processor A. This causes a software
interrupt to be sent to processor A
If A is at PASSIVE_LEVEL then the running thread is interrupted. The
kernel raises the IRQL to DISPATCH_LEVEL, then runs all the DPCs in the
DPC queue. When it’s done it attempts to restore the IRQL to
PASSIVE_LEVEL and lets the thread continue running.
But let’s say T calls KeRaiseIrql(DISPATCH_LEVEL) before the interrupt
arrives. The incoming interrupt is not a higher interrupt level, so the
processor is not interrupted. T continues to run until it calls
KeLowerIrql(…) to go back to PASSIVE_LEVEL. At this point, where the
IRQL drops below DISPATCH_LEVEL, the processor is interrupted. The
interrupt handler will run through and run any queued DPCs before
returning. When it returns the processor is allowed to return to
PASSIVE_LEVEL and the thread T regains control.
Now say thread T wants to acquire a spinlock. It raises IRQL to
DISPATCH_LEVEL and then spins waiting for the lock to be available*.
Spinlock acquisition always happens at or above DISPATCH_LEVEL. If
processor B already owns the lock, then the T will simply spin at
DISPATCH_LEVEL until B releases the lock**. The DPC queue is never
involved in this case.
-p
* - the raise and the spin are both done by KeAcquireSpinLock for you.
** - as an exercise for the reader, think about how I know that
processor A cannot already own the lock if the thread running on
processor A is trying to acquire it (ignoring a broken program)
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vinay Kalkoti
Sent: Thursday, March 30, 2006 10:49 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] DPC query
Folks,
Thanks for the respose. This is what I have understood from the mail
thread and from the book. Please correct me if I am wrong.
DPC/dispatch level is an IRQL which is basically used for sychronizing
objects. When we use spin locks for sychronizing certain variable, the
thread will be queued in the DPC queue if the lock is held by other
thread.
When the IRQL comes to DPC/dispatch level after the running thread
relingishes the IRQL, the kernel will check the DPC queue. If queue is
not empty, then the IRQL will be maintained at DPC/dispatch level and
the threads in the DPC queue will be dispatched.
Correct me if I am wrong.
Thanks,
Vinay
On 3/30/06, Brown, Beverly wrote:
> Of course. I didn’t mean to imply that the drivers should be different
> for UP vs MP. I was just offering a description of the behavior.
>
> Beverly
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of David J. Craig
> Sent: Thursday, March 30, 2006 12:42 PM
> To: Windows System Software Devs Interest List
> Subject: Re:[ntdev] DPC query
>
> The use of different drivers for UP and MP probably wouldn’t work
> well in any case. It might if they were dynamically loaded or based
> upon wether the OS kernel is a UP or SMP edition. Otherwise someone
> could have the /onecpu switch in the boot.ini on one boot option and
> not the other. If it had the kernel & hal boot.ini switches you could
> have a single system boot in UP and SMP mode as desired and have the
> UP and SMP versions of the kernel too.
> Don’t know why you would want it, but someone would try it.
>
> “Peter Wieland” wrote in message
> news:xxxxx@ntdev…
> A few notes on beverly’s explaination:
>
> There are two related concepts here - DPCs and interrupt level.
> Interrupt level controls what can preempt the code currently running
> on the processor and whether the thread can be rescheduled. Code
> running at dispatch-level can still be preempted by a higher prioirty
> interrupt (like a device interrupt) but will not get rescheduled.
>
> You can think of a DPC as a way to inject a dispatch-level interrupt
> into a processor. The DPC routine is sort of like a custom ISR.
> Since the DPC routine runs at dispatch level it can still be
> pre-empted but the thread it interrupted will not be rescheduled.
>
> Also, unless you’re really ready to take on writing two drivers (one
> for UP and one for MP), you should just ignore the system type and
> always synchronize your data properly.
>
> -p
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Brown, Beverly
> Sent: Thursday, March 30, 2006 5:52 AM
> To: Windows System Software Devs Interest List
> Subject: RE: [ntdev] DPC query
>
> A DPC runs at a level where preemption is disabled on the processor
> where it is running. One instance of a DPC is an interrupt DPC and
> would be analogous to a Linux “bottom-half” interrupt (is that what
> they still call it?). It can also be used to run a function to its
> entirety without being preempted (I think Linux has a concept of FIFO
> scheduling - this would be somewhat similar. The driver writer
> controls the queueing of a DPC and they generally get run in FIFO
> order from the processor’s queue.).
>
> Blocking is not allowed in a DPC call. Data is protectected with a
> spinlock on SMP systems in case something on the other processortries
> to access the same data. On single processor systems, only device
> interrupts (linux “top-half” interrupts) can preempt a DPC.
>
> Beverly
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Vinay Kalkoti
> Sent: Thursday, March 30, 2006 6:26 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] DPC query
>
> Hi,
>
> I come from Linux background and trying to understand Windows
internals.
>
> I am reading Inside Microsoft Windows 2000 by David Solomon.
>
> I have a query about DPC. The book specified has something like this
> about DPC.
>
> "Dispatch or deferred procedure call (DPC) interrupts When a thread
> can no longer continue executing, perhaps because it has terminated or
> because it voluntarily enters a wait state, the kernel calls the
> dispatcher directly to effect an immediate context switch. Sometimes,
> however, the kernel detects that rescheduling should occur when it is
> deep within many layers of code. In this situation, the ideal solution
> is to request dispatching but defer its occurrence until the kernel
> completes its current activity. Using a DPC software interrupt is a
> convenient way to achieve this delay. "
>
> It says that DPC’s defer the rescheduling of a process.
>
> My questions are:
> # On what conditions we defer the rescheduling?
> # if we defer the rescheduling and if the current process blocks on
> any object wont the CPU stay idle ?
>
> Waiting for the response.
>
> Thanks,
> Vinay
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer