IRQL is property of a thread or processor

I have basic doubt as to IRQL is a property of a thread or Processor.

and who decides which thread will be running at what IRQL,if its a property of thread.

If its a property of processor then who raises and lowers the IRQL of a processor?

> I have basic doubt as to IRQL is a property of a thread or Processor.

An IRQL defines the hardware priority at which a processor operates at any given time

Hardware and software interrupts at these levels are targeted at individual processors. The following processor-specific IRQLs are commonly used by drivers:
? DISPATCH_LEVEL
? DIRQL
? HIGHEST_LEVEL

IRQLs below DISPATCH_LEVEL are thread specific. Software interrupts at these levels are targeted at individual threads. Drivers use the following thread-specific IRQLs:
? PASSIVE_LEVEL
? APC_LEVEL

and who decides which thread will be running at what IRQL,if its a property of thread.

The system schedules all threads to run at IRQLs below DISPATCH_LEVEL, and the system?s thread scheduler itself (also called ?the dispatcher?) runs at IRQL=DISPATCH_LEVEL. Consequently, a thread that is running at or above DISPATCH_LEVEL has, in effect, exclusive use of the current processor. Because DISPATCH_LEVEL interrupts are masked off on the processor, the thread scheduler cannot run on that processor and thus cannot schedule any other thread.

who raises and lowers the IRQL of a processor?

KeRaiseIrql call, interrupt received on the processor raises current running threads IRQL and spin lock acquisition raise IRQL to DISPATCH_LEVEL.

>I have basic doubt as to IRQL is a property of a thread or Processor.

Both.

Mostly it is a property of the CPU, but the thread also remembers whether it is at APC or PASSIVE level.

and who decides which thread will be running at what IRQL,if its a property of thread.

The KeRaiseIrql/KeAcquireSpinLock calls decide this.

If its a property of processor then who raises and lowers the IRQL of a processor?

KeRaiseIrql does.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> I have basic doubt as to IRQL is a property of a thread or Processor.

Well, IRQL is not really a “property” - it is just a mechanism that Windows uses to implement two totally unrelated concepts known as “atomic context” and “signals desabled” under other OSes.
No wonder that it happens to be a source of endless confusion for Windows kernel newbies.

IRQL >=DISPATCH_LEVEL is an indication of a code running in atomic context. When hardware interrupt occurs a handler stub raises IRQL to DIRQL before invoking ISR, and, after ISR returns control, it lowers IRQL to DISPATCH_LEVEL before procesing DPC chain. By raising IRQL to the level >=DISPATCH_LEVEL you tell the code you are about to invoke that it runs in atomic context, so that it is not allowed to make blocking calls,and, hence, all synchronizaion constructs that it may use have to be only of a spinlock variety. Once you are not allowed to go blocking at
IRQL>=DISPATCH_LEVEL it applies on per-CPU basis,rather than on per-thread one.

,
ISRs and DPCs run at respectively DIRQL and DISPATCH_LEVEL. Any other piece of code that has to synchronize its access to the variables/resources that it shares with ISRs and DPCs must obtain a corresponding spinlock,effectively raising IRQL to the corresponding level (i.e DIRQL for interrupt spinlocks and DISPATCH_LEVEL for the “regular” ones) behind the scenes. KeRaiseIrql() function can raise IRQL as well, but in the world of the multiprocessor machines its practical usefulness is critically close to zero, because it does not work for inter-processor synchronization. The days of uni-processor machines where you could synchronize with ISRs and DPCs simply by raising IRQL are long gone.

IRQL==APC_LEVEL means that signal (known as APC under Windows) delivery to a thread are disabled. This means that a thread cannot get alerted even if it enters the alertable wait.The code that runs at this IRQL is allowed to make blocking calls, which means that this IRQL applies on per-CPU basis. This IRQL is normally used by file system drivers and filters in order to avoid deadlocking scenarios. Therefore, certain API calls that acess fille systems cannot be used at this
IRQL.

IRQL==PASIVE_LEVEL means that there are no restrictions to API calls that a given piece of code can make…

Anton Bassov

>totally unrelated concepts known as “atomic context” and “signals desabled” under other OSes.

Unrelated? so, you can be in atomic context with signals enabled in some OS? :slight_smile:


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

All good answers, I think.

To clarify:

That’s easily misunderstood, and is incorrect as a general statement.

By raising to IRQL >= DISPATCH_LEVEL your code is no longer subject do preemption… that is all this does (in addition to disabling APC delivery, as described separately).

So it will “run to completion” – But only runs in an “atomic context” with respect to other threads running at the same or lower IRQL and ON THE SAME PROCESSOR. As Mr. Bassov knows, code running at IRQL DISPATCH_LEVEL (for example) is subject to interrupts from high IRQL activities.

Peter
OSR
@OSRDrivers

Ah! To the original question:

It is quite literally a property of the processor. The IRQL is a field in the PRCB and is maintained on a per-processor basis.

A thread may change the IRQL of the Processor, but it is not the only potential manager of the processor’s IRQL. Futher, the thread itself does not have the concept of IRQL. A thread only has a concept of IRQL as a side-effect of it being run on a processor, and when it is not running on a processor, it no longer has an IRQL.

Consider that the IRQL of the processor may be changed by the OS for numerous reasons unrelated to the thread that coincidentally happens to be running on the processor (and which is now subject to all the rules of the IRQL change). This happens, for example, when an interrupt is processed.

OK?

NOW… The only thing that makes this concept SLIGHTLY messy is IRQL APC_LEVEL, which messes with individual thread state. But that’s largely a detail to be ignored in the overall architectural discussion.

Peter
OSR
@OSRDrivers

>

That’s easily misunderstood, and is incorrect as a general statement.

More on it below…

By raising to IRQL >= DISPATCH_LEVEL your code is no longer subject do preemption…
that is all this does

Sorry, but, strictly speaking, the above statement is “easily misunderstood, and is incorrect as a general statement” as well, don’t you think - after all, a DPC may be preempted by ISR. The same
observation applies to the term “blocking” as well - the way it is used in the community of kernel developers (particularly UNIX ones) is different from its general usage and definition in English language, so that someone unfamiliar with this terminology may decide that
“cannot block” means that code is noit allowed to spin idly while trying to acquire a spinlock…

But only runs in an “atomic context” with respect to other threads running at the same
or lower IRQL and ON THE SAME PROCESSOR.

As you must know, the terms like “atomic context” , “preemption” and “blocking” are normally used in the community of system-level developers only in respect to the possibility of thread context switches - by saying that a piece of code “runs in atomic context”, “cannot be preempted” or “cannot go blocking” one means that context swicthes are not allowed while this code runs, alhough such community-specific usage of these terms may be different from their general usage/definition in Englih language…

Anton Bassov

While I agree with your characterization of preemption and blocking, which apply to scheduling, I disagree with you characterization of the term “atomic context” – When I say an operation, such as updating the registers on my device, I expect those registers to be updated in one continuous operation and without interference irrespective of the CPU from which the interference may occur. Similarly, when I want to ensure atomic access to a set of shared data structures, such as a pointer and an accompanying buffer, I want these to be updated together with no chance of an intervening operation, regardless of the processor from which that interference comes.

Peter
OSR
@OSRDrivers

> While I agree with your characterization of preemption and blocking, which apply to scheduling,

I disagree with you characterization of the term “atomic context”

Well, it was not me who invented/introduced these terms,right - I just “dumbly use” the existing terminology…

https://lwn.net/Articles/274695/

I don’t want to say that this terminology provides a perferctly accurate description of things. For example, a widely used term “process context” is obviously a misnomer - after all, what would one say about the kernel worker threads. Therefore, I prefer to use the one “thread context” instead…

Anton Bassov

> Unrelated? so, you can be in atomic context with signals enabled in some OS? :slight_smile:

Of course - after all, the very fact that signal delivery is enabled does not necessarily imply that
a pending signal is going to be actually delivered right on the spot, right. For example, under UNIX-like OSes signals are meaningless until you are about to return to the userland. Under Windows a thread may receive a kernel APC while it is in a kernel mode, but, in order for this APC to get actually delivered to a thread, dispatching must be, at the very minimum, enabled on a given CPU.

In other words, as long you are in atomic context you simply cannot be bothered about the signals, so that these two concepts are totally unrelated…

Anton Bassov