why do we mask IRQs on x86?

Ingo Molnar (mingo@pc5829.hil.siemens.at)
Wed, 23 Apr 1997 11:08:42 +0200 (MET DST)


our current scheme for handling IRQs is the following:

[all IRQs are unmasked]

1- IRQ x is raised
2- we go into the irq.h handler part, all irqs are masked off (cli mode)
3- we mask IRQ x in the 8259A PIC [thus we exclude this specific IRQ source]
4- we ack the pending IRQ in the 8259A PIC
5- we call do_IRQ() {or do_fast_IRQ()}
6- the handler installed via request_irq() is called

7- [driver specific handler executes]
8- {in case of shared IRQ lines another handler is called as well}

9- we get back into the irq.h handler part, and unmask IRQ x in the 8259A
10- iret [restores flags as well]

The above ack/mask trick is done to support 1) enabling irqs via sti() in
the handler 2) to shorten the period while the 8259A is "unacked".

Is there any reason why we dont do the following: [changes marked with (*)]

1- IRQ x is raised
2- we go into the irq.h handler part, all irqs are masked off (cli mode)
(*) 3- we do NOT mask IRQ x in the 8259A, instead we increase a per-IRQ
counter which says 'serving this IRQ'.
4- we ack the pending IRQ in the 8259A PIC
(*) 4b- If the IRQ count for IRQ x is not 1, we simply return via iret.
5- we call do_IRQ() {or do_fast_IRQ()}
6- the handler installed via request_irq() is called

7- [driver specific handler executes]
8- {in case of shared IRQ lines another handler is called as well}
(*) 8b- decrease IRQ count for IRQ x, repeat 7- if count nonzero

(*) 9- <no need to umask IRQ x>
10- iret [restores flags as well]

It is important to do the counter loop in 8b, because in case of shared
interrupts we want to give equal chance for all handlers on the handler
chain.

Benefits:

- we get rid of the IRQ masking/umasking thing, which is a couple of very
slow ISA cycles even on the fastest PPro systems AFAIK.

We might get interrupted while handling the previous interrupt, but this
is not a problem in case of single interrupt sources (most cards need a
special command anyways to ack the IRQ).

In case of shared interrupts, we do not increase the number of interrupts.
In the current scheme, once we unmask the IRQ on the 8259A, and there is a
pending interrupt, we get interrupted almost immediatelly.

about bad cards irq flooding us: in that case the system executes that
handler almost always anyways ... does the proposed scheme make much
difference?

is there anything obviously broken in this scheme?

-- mingo