Re: linux-kernel-digest V1 #106

Linus Torvalds (Linus.Torvalds@cs.helsinki.fi)
Thu, 6 Jul 1995 09:13:36 +0300


mucci@cs.utk.edu: "Re: linux-kernel-digest V1 #106" (Jul 5, 16:31):
>
> I've been following this discussion of fast and slow interrupt for a while
> and I'm a bit confused. Basically it concerns the API interface to the two of them.
>
> 1) How does one register a *fast* interrupt.

request_irq(irq_nr, irq_fn_pointer, flag, device_name);

where "flag = 1" for a fast interrupt, and 0 for a normal one.

> 1.1) What calls need to be made when entering a critical section in a fast interrupt?

Inside the interrupt itself you don't need to do anything: the interrupt
code is automatically a critical section with all interrupts disabled.

If you want to protect some critical section _from_ a fast interrupt,
you should do:

unsigned long flags;

save_flags(flags);
cli();
.. critical code ..
sti();

Another method is to do a "disable_irq(irq_nr)/enable_irq(irq_nr)" pair,
but that is _slow_, and as such useful mainly for some major setup
operations that can take a long time. I'd strongly suggest not using
these (they can also not be made re-entrant, as there is no way to get
the current endable/disable status).

> 2) Same as one but for slow interrupt.
> 2.1) Ditto.

The issues for a slow interrupt are essentially the same as above
(except that "flag" is 0 when requesting the interrupt). The driver
itself shouldn't notice any difference: other interrupts may interrupt
the slow interrupt handler, though, so if you have multiple interrupts
messing with the same data (bad idea!), you'd need to do cli/sti pairs
inside the slow interrupt handler.

The third interrupt type is the software interrupt, aka "bottom half
handler". The issues here are completely different: they are more like
signal handlers for the kernel than interrupts. If you're interested,
the terminal drivers or the networking code may be worth looking into.

> Next topic:
>
> I'm in the process of porting the x86 serial driver to Amiga Linux running
> a prototype ISA->Zorro Bus converter. The Amiga/Atari/Alpha ports have already been
> abstracted into HW dep and indp parts. Any idea when we'll see this for the x86
> source tree?

It will take a while (and, btw, the alpha port has the same bus
structure as the i386 port, so it's already fully integrated into the
newer kernels).

> Why is it that interrupts are registered at init time and not open time
> for drivers. Would there be any significant time savings by register the
> handler at open time? At least then the kernel wouldn't have to decend the chain...

Some drivers register the irq's at open time, others do it at init time.
It's up to the driver, as long as the kernel is able to handle spurious
interrupts for devices that haven't registered.

> The Amiga and the Atari don't have I/O space. However, this new card creates
> such a memory region. Looking through code like libvga shows the use of an ioperm
> system call to gain (exclusive?) access. I think I remember reading that this
> is handled in HW by the x86. Could I emulate this system call by just checking
> a bitmask in an uninterruptable state? Are all the IO registers available? Seems
> kind of dangerous to me...

If you don't have io space, you don't need ioperm. On the 68k family
(and others without IO space), the equivalent of ioperm() is simply
'mmap("/dev/mem",...)' to get the IO memory region allocated into the
user process.

>From kernel mode, you'd just access the memory directly, of course. If
you want to re-use existing i386 code that uses IO mappings, you
probably watn to hide the accesses behind a macro called "inb()" and
"outb()", though ;-)

> The x86 linux allows raw device access. Why the #$^&! doesn't 680x0 Linux?
> BTW, I only get 150K/sec through my A3000 SCSI to a quantum and a seacrate. This
> seems disgustingly slow. This is why I'd like to have raw device access so I can see
> whether the driver or the cache is slow...Under the native OS, (still pre-emptive
> with a buffer cache) I can see megabytes per second. What gives?

x86 linux doesn't allow raw disk accesses. I think it's hugely ugly.
All disk accesses go through the buffer cache ("optimize for the common
case, not for the nutcase").

> P.S. Could someone give me a general run-down on the serial driver?
> P.P.S. Why is the serial driver so darn fat?

The serial driver is do darn fat because the hardware is so strange. A
single chip revision wouldn't be a problem, but when you have lots of
(slightly) different chips, coupled together with the rather braindead
ISA interrupt sharing issues, you get that monster.

> P.P.P.S. What causes a general protection fault under the x86 linux.

Anything which accesses outside a segment (trying to access kernel space
above the 1GB mark, for example). Or writing to a read-only segment.
Or using a 0 segment register. Or trying to access a gdt/idt/ldt entry
that isn't defined. (and probably a few other reasons too, which I've
happily forgotten about).

Linus