Re: Interrupt semantics

Linus Torvalds (torvalds@transmeta.com)
Wed, 16 Apr 1997 10:48:24 -0700 (PDT)


[ Cc'd to the kernel list as well, because this is not de4x5-specific.
Indeed, to some degree the de4x5 driver is one of the few ones that no
longer need to worry about the issue other than for maintenance ]

On Wed, 16 Apr 1997, David C. Davies wrote:
>
> > (cut-and-paste from the de4x5 driver that had this problem):
> >
> > DISABLE_IRQs; /* Ensure non re-entrancy */
> > synchronize_irq();
> > dev->interrupt = MASK_INTERRUPTS;
>
> Can you point me to an explanation of the problem or give me a quick thumbnail
> sketch so I can figure it into my next release.

The thing is pretty simple, and not hard to handle (as you can see, it's
just adding a synchronization point). What is going on is this:

CPU #0 CPU #1

- is somewhere in bh handling
- gets a de4x5 interrupt - calls "hard_xmit_start"
- de4x5.c does "DISABLE_IRQs"
- IRQ is _already_ running - CPU #0 and CPU #1 are both
executing in the critical
region.

So the bad thing is just that another CPU may _already_ be servicing
interrupts when we do the card-level interrupt disable, and obviously any
old interrupts won't magically cease to exist. As such, the act of
disabling the hardware interrupts is no longer sufficient to guarantee
non-re-entrancy.

[ Aside - "cli()/sti()" do the appropriate synchronization, and they are
always safe. It is only when a driver disables its _own_ interrupts some
way that the extra synchronization point is needed ]

What the "synchronize_irq()" function does is to just wait until no other
CPU is no longer servicing interrupts (so on UP, it obviously doesn't need
to do anything at all).

Note that the "synchronize_irq()" call has to be _after_ we have disabled
the card interrupts to ensure proper working - otherwise there would again
be a small window where an interrupt could happen on another CPU in
between the synchronize call and the irq disable.

Final note: on UP there is no overhead at all in synchronize_irq(),
because it's an empty #define in that case. On SMP it is also pretty
low-overhead (it may end up spinwaiting for another CPU doing interrupts,
but that is pretty unlikely and we have to wait there anyway). So you
don't need to be overly concerned about the performance impact of this.

> I'm about to update de4x5.c again, so would like any SMP issues included...

This was the only issue - other than this specific interrupt case the
driver interfaces are not affected at all. I hope to keep it that way, so
that device driver authors wouldn't need to know about SMP issues.

Linus