Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Raising a driver's IRQL above DIRQL

179 views
Skip to first unread message

Alex Sheffield

unread,
Nov 29, 2001, 1:12:59 PM11/29/01
to
I have a driver in which I must perform a series of hardware register
write operations in less than 5 usec. My routine to do this is very
fast and runs at DIRQL. However, since this is still not the highest
possible IRQL priority, I am worried that something else can still
interrupt me. If this "something else" happens during my routine and
takes longer than a 3-4 usecs, then my routine is hosed.

My question then is, is it safe to temporarily raise my IRQL beyond
DIRQL? Or, is this not necessary, i.e. the only things that run
higher than DIRQL are things that operate extremely briefly, like
timer updates, NOT other kernel mode drivers?

Thoughts...??

Thanks!
Alex

Mark Roddy

unread,
Nov 29, 2001, 5:56:16 PM11/29/01
to
If you really have to guarantee that a series of operations must
proceed in your 5us window, then yes sure you should raise your IRQL
above *anything* that can interrupt you. I'd go for HIGH_LEVEL myself.
However, if this window includes interrupt latency, you might as well
not bother as you can't fix that on this platform.

Your DIRQL, by the way, may be lower than other device drivers. as
DIRQL is a place holder for a range of interrupts assigned to devices,
so it isn't just timer interrupts and IPI interrupts that can clobber
you.

On Thu, 29 Nov 2001 18:12:59 GMT, alex...@dps.com (Alex Sheffield)
wrote:

=
Mark Roddy
WindowsNT Windows2000 Consultant
Hollis Technology Solutions
http://www.hollistech.com
ma...@hollistech.com
603-321 1032

Spiro Trikaliotis

unread,
Nov 30, 2001, 7:41:28 AM11/30/01
to
Hi,

On Thu, 29 Nov 2001 17:56:16 -0500, Mark Roddy wrote:

>If you really have to guarantee that a series of operations must
>proceed in your 5us window, then yes sure you should raise your IRQL
>above *anything* that can interrupt you. I'd go for HIGH_LEVEL myself.
>However, if this window includes interrupt latency, you might as well
>not bother as you can't fix that on this platform.

What about masking the interrupts? From my understanding, the IRQL
is handled inside the interrupt code, so the OS might get control
even with IRQL=HIGH_LEVEL?

BTW, I've done this before (IRQL=HIGH_LEVEL and masking out IRQs),
and it seems to work as far as you're not stalling everything for
too much time.

Spiro.

Walter Oney

unread,
Nov 30, 2001, 8:29:14 AM11/30/01
to
Spiro Trikaliotis wrote:
> What about masking the interrupts? From my understanding, the IRQL
> is handled inside the interrupt code, so the OS might get control
> even with IRQL=HIGH_LEVEL?

Raising the IRQL to HIGH_LEVEL is the equivalent if disabling the CPU
for interrupts and is platform portable. Putting an _asm block into a
driver (if that's how you're masking interrupts) makes the source not
portable.

--
Walter Oney
http://www.oneysoft.com

Gennady Mayko

unread,
Nov 30, 2001, 10:55:33 AM11/30/01
to
I think that in this particular case the most simple way to be not
interrupted is to disable interrupts at the beginning and enable them
at the end of this fast routine (for ex., for x86 platform using
cli/sti instructions).

Regards,
Gennady Mayko.

Mark Roddy <mro...@tellink.net> wrote in message news:<d1fd0u4o2lirs8789...@4ax.com>...

Alex Sheffield

unread,
Nov 30, 2001, 1:24:26 PM11/30/01
to

Thank you everyone for your responses. I'm assuming both methods are
multi-processor safe? Or rather, I would assume multi-processor is
simply not an issue, i.e. what do I care what another processor is
doing, as long as my code is allowed to run concurrently.

I'm not so sure I want to raise my IRQL all the way to HIGH_LEVEL to
mask interrupts completely. My code operates reasonably fast, but not
so fast that it's a trivial amount of time. I don't want to interfere
with the updating of timers for example. Basically, all I want to do
is to make sure other people's driver code doesn't run, and I'm hoping
I can trust the OS to not take too long doing anything at above DIRQL
level.

So really, my question is what is the best value to raise my IRQL to
that lies between DIRQL and HIGH_LEVEL? Or, are you guys telling me I
still can't trust *any* interrupt routines to execute in less than 5
usec, including all of those that run above DIRQL?

Thanks,
Alex

Spiro Trikaliotis

unread,
Dec 5, 2001, 6:26:00 AM12/5/01
to
Hi Walter,

On Fri, 30 Nov 2001 08:29:14 -0500, Walter Oney wrote:

>Raising the IRQL to HIGH_LEVEL is the equivalent if disabling the CPU
>for interrupts and is platform portable. Putting an _asm block into a

Have you checked it on a real system?

My problem with IRQL is, that the system has to check somewhere if the
"requested" IRQL is higher than the current one. So, an IRQ, for
example, will get executed and a quick test has to be performed (and
the IRQ has to be put in a queue if necessary). At least, that's what
I think about IRQL processing.

So, the only possibility to circumenvent this is to *really* mask
interrupts. So, the question is: Does NT itself mask interrupts when
on HIGH_LEVEL? If not, setting IRQL to HIGH_LEVEL might not be
sufficient.

Spiro.

Spiro Trikaliotis

unread,
Dec 5, 2001, 6:28:40 AM12/5/01
to
Hi Alex,

On Fri, 30 Nov 2001 18:24:26 GMT, Alex Sheffield wrote:

>So really, my question is what is the best value to raise my IRQL to
>that lies between DIRQL and HIGH_LEVEL? Or, are you guys telling me I
>still can't trust *any* interrupt routines to execute in less than 5
>usec, including all of those that run above DIRQL?

I have seen a (very popular!) network driver's source where all the
interrupt processing was done inside of the ISR (which, IIRC, runs at
DIRQL, doesn't it? - Can anyone with more NDIS expertise jump in
here?). So, the time for execution *can* be considerably higher.

Spiro.

Stephan Wolf

unread,
Dec 5, 2001, 11:00:29 AM12/5/01
to
Well, I actually wrote an NDIS Miniport driver, which did all the PIO
copying of received packet data from the device to system memory in
the ISR (shame on me). This was on a Windows CE system.

However, the device only had 128K of "on-board" memory and about 2/3
of it were set up for receiving packets. Since the hardware uses 2K
blocks per received frame regardless of the frame size, mimimum size
frames can blow receive buffer space in about 0.4ms when in 100 Mbps
mode (IIRC). Thus, the receive FIFO needs to be emptied asap. The
delay between the ISR and the DPC was just too long if the system is
busy.

Stephan
---
On Wed, 05 Dec 2001 11:28:40 GMT, Trik...@gmx.de (Spiro Trikaliotis)
wrote:

Alex Sheffield

unread,
Dec 5, 2001, 1:34:44 PM12/5/01
to
On Wed, 05 Dec 2001 11:28:40 GMT, Trik...@gmx.de (Spiro Trikaliotis)
wrote:

>On Fri, 30 Nov 2001 18:24:26 GMT, Alex Sheffield wrote:

Oh yes, I definitely realize that there are going to be drivers out
there that spend a fair bit of time at DIRQL. In fact, that's exactly
my point.

Perhaps I should rephrase my question. What is the best value to
raise my IRQL to that lies between -- but not including -- DIRQL and
HIGH_LEVEL. (DIRQL is too low for me, HIGH_LEVEL is too high for me.)
I don't need to mask interrupts completely, I just don't want to get
pre-empted for a long period of time by some other driver, which can
happen at DIRQL.

Thanks,
Alex

Maxim S. Shatskih

unread,
Dec 5, 2001, 2:59:53 PM12/5/01
to
> interrupts. So, the question is: Does NT itself mask interrupts when
> on HIGH_LEVEL?

Yes, it is the same as "cli".

Max

Hao Guan

unread,
Dec 5, 2001, 11:58:24 PM12/5/01
to
> What about masking the interrupts? From my understanding, the IRQL
> is handled inside the interrupt code, so the OS might get control
> even with IRQL=HIGH_LEVEL?

Yes, you're right. processor running at HIGH_LEVEL doesn't really mask
interrupt. At least, this is true for a uni-processor machine. KeRaiseIrql
and KeLowerIrql exported by hal.dll only modifies the the CurrentIrql of the
Processor Control Block struct and some flag in the kernel which it's not
very clear to me. No hardware/PIC IMR is being updated. When an interrupt
comes in, the interrupt dispatcher will compare the interrupt's associated
IRQL with the current IRQL, if the former is higher, the new ISR will get
call and the running routine/ISR is preempted.

We can do cli/sti on an uni-processor machine(i386 only), hal.dll also
exports 2 undocumented
apis -HalDisableSystemInterrupt/HalEnableSystemInterrupt which is
platform-independent.

For a mps machine, things are not that clear and I'm still looking at the
code to figure out how the IRQL are implemented.
"Spiro Trikaliotis" <Trik...@gmx.de> wrote in message
news:3c0e03a6....@news.cis.dfn.de...

Assaf Wodeslavsky

unread,
Dec 7, 2001, 4:53:01 PM12/7/01
to
then when an interrupt occurs it is ignored
but then it again interrupts
meaning: the processor is stuck
in an infinite loop beeing interrupted
only to end up ignoring the interrupt

are you sure about this?
if you don't mask out the interrupts you have NO system

assaf


"Hao Guan" <calv...@sympatico.ca> wrote in message
news:ATCP7.23149$iF3.2...@news20.bellglobal.com...

Ntdev Reader

unread,
Dec 8, 2001, 11:39:30 PM12/8/01
to
"Maxim S. Shatskih" <ma...@storagecraft.com> wrote in message news:<9um478$2sro$8...@gavrilo.mtu.ru>...

What do you mean by "the same as"? Does it execute the CLI instruction?

Regarding other IRQLs, I've heard that NT doesn't really mask any interrupts
in the interrupt controller until an interrupt that is supposed to be
masked at the given IRQL really happens while the CPU is at the IRQL. Only
then will NT mask the interrupt. This is surely for performance reasons.
This means that the original poster's ISR will get interrupted for as
long as it will take NT to disable the interrupt and do whatever it does
around it. I have no idea how long does it take. So, if he has no other
way around, his best bet might be to raise to HIGH_LEVEL and also execute
CLI, unless Max assures us that NT will do it for him.

Mark Roddy

unread,
Dec 9, 2001, 11:44:53 AM12/9/01
to

I believe that for APIC systems it is sufficient to set the interrupt
mask on the processor, and that is done by KeRaiseIrql. You don't need
to do a CLI, if the processor mask prohibits an interrupt, the APIC
will not deliver that interrupt to that processor.

Ntdev Reader

unread,
Dec 10, 2001, 12:18:03 AM12/10/01
to
ntde...@yahoo.com (Ntdev Reader) wrote in message news:<fa2ebae4.01120...@posting.google.com>...

> "Maxim S. Shatskih" <ma...@storagecraft.com> wrote in message news:<9um478$2sro$8...@gavrilo.mtu.ru>...
> > > interrupts. So, the question is: Does NT itself mask interrupts when
> > > on HIGH_LEVEL?
> >
> > Yes, it is the same as "cli".
> >
> > Max
>
> What do you mean by "the same as"? Does it execute the CLI instruction?
>
> Regarding other IRQLs, I've heard that NT doesn't really mask any interrupts
> in the interrupt controller until an interrupt that is supposed to be
> masked at the given IRQL really happens while the CPU is at the IRQL. Only
> then will NT mask the interrupt. This is surely for performance reasons.

This is incorrect. At least, KeRaiseIrql in halacpi.dll from Win2K DOES
mask interrupts in the interrupt controller. Also, it does not execute
CLI for HIGH_LEVEL. This halacpi.dll has a table of 32 elements, one for
every possible IRQL, and elements contain masks to be written into the
controller. Strangely, the masks for the HIGH_LEVEL are 0xFA for the
primary controller and 0xFF for the secondary. That the bit 2 is clear
is fine, since it is used to chain the secondary controller, but why
is the bit 0 clear? It is clear for every single IRQL. Does anybody
on this newsgroup know why? Looks like even when you raise to HIGH_LEVEL
you still might be interrupted by the timer. Is the bit 0 still the timer?
It was, when I programmed for DOS, but so many new exciting things happened
since then...

Andrew Naiden

unread,
Dec 13, 2001, 8:44:03 PM12/13/01
to
> > Regarding other IRQLs, I've heard that NT doesn't really mask any
interrupts
> > in the interrupt controller until an interrupt that is supposed to be
> > masked at the given IRQL really happens while the CPU is at the IRQL.
Only
> > then will NT mask the interrupt. This is surely for performance reasons.
>
> This is incorrect. At least, KeRaiseIrql in halacpi.dll from Win2K DOES
> mask interrupts in the interrupt controller. Also, it does not execute
> CLI for HIGH_LEVEL. This halacpi.dll has a table of 32 elements, one for
> every possible IRQL, and elements contain masks to be written into the
> controller. Strangely, the masks for the HIGH_LEVEL are 0xFA for the
> primary controller and 0xFF for the secondary. That the bit 2 is clear
> is fine, since it is used to chain the secondary controller, but why
> is the bit 0 clear? It is clear for every single IRQL. Does anybody
> on this newsgroup know why? Looks like even when you raise to HIGH_LEVEL
> you still might be interrupted by the timer. Is the bit 0 still the timer?
> It was, when I programmed for DOS, but so many new exciting things
happened
> since then...

Maybe it is on halacpi.dll,
But on my old APIC based motherboard (Dual PII-300) there is nothing masked
in controller.
I just looked in Softice: there is also a table like you said, but simply a
new vaue is taken from table and stored in some
variable, nothing more... So CLI is absolutely needed if you don't want to
get interrupted.

Andrew

Jan Houska

unread,
Dec 14, 2001, 3:37:50 AM12/14/01
to
Hi,

But isn't that variable a memory-mapped APIC register? At least this is
how I understand the halapic.dll code. So the masking does happen there
after all. However, CLI won't hurt if you a) re-enable interrupts soon
enough and b) give up on portability outside x86 world.

Jan


====================================================================
Jan Houska HUMUSOFT s.r.o.
hou...@humusoft.com Novakovych 6
http://www.humusoft.com 180 00 Praha 8
tel: ++ 420 2 84011730 Czech Republic
fax: ++ 420 2 84011740
====================================================================

Andrew Naiden

unread,
Dec 14, 2001, 6:34:52 AM12/14/01
to
> > But on my old APIC based motherboard (Dual PII-300) there is nothing
masked
> > in controller.
> > I just looked in Softice: there is also a table like you said, but
simply a
> > new vaue is taken from table and stored in some
> > variable, nothing more... So CLI is absolutely needed if you don't want
to
> > get interrupted.
>
> But isn't that variable a memory-mapped APIC register? At least this is
> how I understand the halapic.dll code. So the masking does happen there
> after all. However, CLI won't hurt if you a) re-enable interrupts soon
> enough and b) give up on portability outside x86 world.


Yes, I must apologize and correct myself.... A more closer examination shows
that this memory adress (0xFFFE0080)
in fact belongs to 'System board' address spece. I guess it is some APIC
mask register.
So interrupts seem to be masked indeed.

Andrew

Andrew Naiden

unread,
Dec 14, 2001, 6:34:52 AM12/14/01
to
> > But on my old APIC based motherboard (Dual PII-300) there is nothing
masked
> > in controller.
> > I just looked in Softice: there is also a table like you said, but
simply a
> > new vaue is taken from table and stored in some
> > variable, nothing more... So CLI is absolutely needed if you don't want
to
> > get interrupted.
>
> But isn't that variable a memory-mapped APIC register? At least this is
> how I understand the halapic.dll code. So the masking does happen there
> after all. However, CLI won't hurt if you a) re-enable interrupts soon
> enough and b) give up on portability outside x86 world.

Ntdev Reader

unread,
Dec 14, 2001, 1:38:17 PM12/14/01
to
"Andrew Naiden" <ve...@NOSPAM.solar.unity.net> wrote in message news:<9vcof4$li8$1...@hyppo.gu.net>...

So, what does your halapic.dll masks for HIGH_LEVEL? My halacpi.dll
doesn't seem to mask the timer interrupt.

I must confess I did not step through it in the debugger, I only looked
through the instructions and the mask table. The instructions seem to take
the mask from the table, OR it with a mask indicating which interrupts
do not have handlers "connected" through IoConnectInterrupt, and then write
the result into the primary and secondary interrupt controllers. I have not
really verified that the second "not connected interrupt" mask doesn't
have the timer bit set, but the timer bit is clear in the mask table.
That it is treated specially in the mask table makes me suspect that it might
not always be disabled on HIGH_LEVEL.

Jan Houska

unread,
Dec 20, 2001, 3:55:58 AM12/20/01
to
Hi,

Ntdev Reader wrote:

<snip>

> So, what does your halapic.dll masks for HIGH_LEVEL? My halacpi.dll
> doesn't seem to mask the timer interrupt.
>
> I must confess I did not step through it in the debugger, I only looked
> through the instructions and the mask table. The instructions seem to take
> the mask from the table, OR it with a mask indicating which interrupts
> do not have handlers "connected" through IoConnectInterrupt, and then write
> the result into the primary and secondary interrupt controllers. I have not
> really verified that the second "not connected interrupt" mask doesn't
> have the timer bit set, but the timer bit is clear in the mask table.
> That it is treated specially in the mask table makes me suspect that it might
> not always be disabled on HIGH_LEVEL.

To me it looks like this:

APIC HALs (halapic.dll, halmps.dll, halaacpi.dll, halmacpi.dll) mask all
interrupts on the APIC immediately after raising IRQL to HIGH_LEVEL.

ACPI HAL (halacpi.dll) masks all interrupts on the PIC immediately after
raising IRQL to HIGH_LEVEL.

PC HAL (hal.dll) only remembers that IRQL is set to HIGH_LEVEL. If later
an interrupt comes it does not process it but just queues it and then
masks all interrupts on the PIC.

Of course, the queuing does take some time so you get interrupted for a
while. So CLI is safest if you really want to guarantee no interrupts at
all.

BTW, does anyone have some insight why the PC HAL behaves as it appears
to behave? Apparently they care not to lose some important interrupt,
but why this isn't an issue with other similar HALs like ACPI?

Maxim S. Shatskih

unread,
Dec 20, 2001, 4:29:58 PM12/20/01
to
> So, what does your halapic.dll masks for HIGH_LEVEL? My halacpi.dll
> doesn't seem to mask the timer interrupt.

Is HALAPIC used for uniprocessors at all?
Am I wrong that uniprocessor NT uses APICs only in 8259-compatible mode with good old port 0x20 and such?

Max

Ntdev Reader

unread,
Dec 20, 2001, 7:08:42 PM12/20/01
to
> > So, what does your halapic.dll masks for HIGH_LEVEL? My halacpi.dll
> > doesn't seem to mask the timer interrupt.
> >
> > I must confess I did not step through it in the debugger, I only looked
> > through the instructions and the mask table. The instructions seem to take
> > the mask from the table, OR it with a mask indicating which interrupts
> > do not have handlers "connected" through IoConnectInterrupt, and then write
> > the result into the primary and secondary interrupt controllers. I have not
> > really verified that the second "not connected interrupt" mask doesn't
> > have the timer bit set, but the timer bit is clear in the mask table.
> > That it is treated specially in the mask table makes me suspect that it might
> > not always be disabled on HIGH_LEVEL.
>
> To me it looks like this:
>
> APIC HALs (halapic.dll, halmps.dll, halaacpi.dll, halmacpi.dll) mask all
> interrupts on the APIC immediately after raising IRQL to HIGH_LEVEL.
>
> ACPI HAL (halacpi.dll) masks all interrupts on the PIC immediately after
> raising IRQL to HIGH_LEVEL.
>
> PC HAL (hal.dll) only remembers that IRQL is set to HIGH_LEVEL. If later
> an interrupt comes it does not process it but just queues it and then
> masks all interrupts on the PIC.
>
> Of course, the queuing does take some time so you get interrupted for a
> while. So CLI is safest if you really want to guarantee no interrupts at
> all.

What is the nature of you information source? Did you actually execute
the "raise to HIGH_LEVEL" and then looked into the interrupt controller?
Or, did you step through the code and saw how it formed the final masks
for the interrupt controller? If so, how does W2K halacpi.dll come to mask
all of the interrupts? Does it have, contrary to what I saw, the
timer interrupt bit set in the mask table?

>
> BTW, does anyone have some insight why the PC HAL behaves as it appears
> to behave? Apparently they care not to lose some important interrupt,
> but why this isn't an issue with other similar HALs like ACPI?

According to your words above, after an interrupt happens, they physically
mask the interrupts. So, it doesn't seem like they care "not to lose
some important interrupt".

0 new messages