Re: Interrupts continued

Linus Torvalds (torvalds@transmeta.com)
Sat, 11 Jul 1998 21:29:13 -0700 (PDT)


On Sat, 11 Jul 1998, Alan Cox wrote:
>
> 2.1.x uniprocessor is Ok providing you build with SMP=0 - ie when its using
> hardware cli/sti and SA_INTERRUPT. The latency is still much worse for some
> reason. Probably the interrupt return path as the entry path is pretty clean

You shouldn't even have compared the SMP=1 case to 2.0.x with SMP=0, as
however bad 2.1.x is in SMP it cannot even touch the latencies that 2.0.x
had (you could have latencies on the order of tens of milliseconds by just
forcing a kernel system call to copy memory on the non-irq CPU).

The reason 2.1.x probably has longer interrupt latency is probably the
disk layer. It disables interrupts for too long, because it was simply too
buggy without that on SMP.

> 2.1.x SMP with one CPU or more than one recurses through the entire kernel
> space and explodes. I'll try and debug this in more detail if I can catch
> the machine enough to see what happened.
>
> Anyway Im now off to look at putting the notion of fast interrupt and
> probably syscall returns back into 2.1.x.

Don't bother with the "fast interrupt". It was never any faster than the
slow one. It had slightly different semantics wrt the return path, but the
original meaning of the fast interrupt was that it wouldn't play any games
with the interrupt controller, because it would never enable interrupts,
so there were no re-entrancy issues. Not playing any interrupt controller
games meant avoiding the overhead of several IO instructions, and that
would have been meaningful.

That was in pre-1.0.x days - even fast interrupts were changed to mask the
interrupt controller because too many people wanted them. The only
difference between a fast and a slow interrupt was that the fast one
didn't do the bottom half handling, and didn't check for signals, and due
to that a lot of people actually complained about ppp latencies etc.

What you _should_ do, and what the code is actually set up to support
already, is to instead of having the notion of "fast" vs "slow" (which was
completely broken), you should look into having the interrupt routines
return a value. The return path can then check whether it should do bottom
halves or not depending on that value.

This is because a lot of the things that really want fast interrupts,
don't actually want the interrupts to be _always_ fast, they want them to
be fast most of the time. The static "SA_INTERRUPT" flag was too static.

For example, if you have high-speed serial devices, they usually do not
want to do a bottom half for each interrupt. However, to avoid latency
problems with packets etc, they _do_ want to be able to say "ok, my
ping-pong buffer is getting full, please do a bottom half interrupt now",
or "ok, I got the end-of-packet marker, now it makes sense to get a whole
packet, so do the bottom half now".

And THEN they want the bottom half handler to be done immediately.

This is actually completely done already, if you look at irq.c. The only
part that is missing is the return value from the interrupt handlers, so
right now the code has something like

if (1) {
if (bh_active & bh_mask)
do_bottom_half();
}

while it instead should look something like

flags = irq_desc[irq].handler->handle(irq, cpu, &regs);

if (flags & INTERRUPT_DO_BH) {
if (bh_active & bh_mask)
do_bottom_half();
}

if (flags & INTERRUPT_DO_SIGNALS) {
return through signal checking code
}

but it would mean that every interrupt handler woul dhave to return a
value (it might not be too painful to just make them all return 0, and
then one by one the ones that know about their needs could be changed).

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html