Subject: Re: i386 interrupt mask questions
To: Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
From: Chris G Demetriou <Chris_G_Demetriou@lagavulin.pdl.cs.cmu.edu>
List: port-i386
Date: 06/30/1995 07:39:53
[ if this is ... inconsistent, it's because i wrote it three or so
  passes, and so things may have gotten mangled... ]


> 1. The line discipline l_rint and l_start procedures will be called
> by a tty driver (such as com.c) at spltty or higher, so other interrupts
> from tty devices are blocked.

yup.


> 2. With PPP in the kernel, code running at splimp won't be interrupted
> by a tty device interrupt.

true, but only necessarily so if the kernel was compiled properly
(i.e. 'make depend'ed, or compiled from scratch).  if the kernel was
miscompiled (e.g. by having PPP added the the config file, and then
having the kernel built w/o a 'make depend' or 'make clean'), it's
possible that it wouldn't be true.


> 3. Code running at spltty or splimp won't be interrupted to run
> softclock() (and thus any routine registered with timeout()) or
> softnet().  [I would expect this, but I can't convince myself that
> it is true on the i386.]

code running at either spltty() or splimp() will not be interrupted to
run softclock().

code running at spltty() _MAY_ be interrupted to run softnet() (at
least, that's what it looks like from looking at the code).  In my
opinion, this is an x86-ism, that is _NOT_ true to the original way
software interrupts were done.  In particular (if i recall properly),
on the VAX, software interrupts were all lower priority than 'real'
interrupts, and if you blocked _any_ real interrupts, then you blocked
_all_ software interrupts.  (see below for further discussion of
this...)


> 4. The line discipline l_open, l_close, l_read, l_write, and l_ioctl
> routines are never called from an interrupt routine, so code running
> at spltty, splimp or splnet won't be interrupted to run any of these
> routines.

this should be true.


> 5. Routines called by softnet() are run at splnet.

_no_.  they're called at 'splsoftnet()'

On the i386, splsoftnet() blocks _only_ other network software
interrupts and softclock.  on some/most other ports, splsoftnet() is
the same as splsoft(), all blocks _all_ software interrupts.
(the other type of software interrupt currently defined on the x86 is
software TTY interrupts, but they're not actually used for anything 
right now, so they can't be a problem.)

Note that splsoftclock _doesn't_ block software networking interrupts
(or, at least, that's what i get from reading the code).  however,
this shouldn't be a problem, because any critical sections in code run
from softclock should protect themselves with spl's.


I you think the i386's implementation might be a problem, i'd like to
hear about it.  I must admit that i do not now, and never have,
trusted the i386's software interrupt handling.  (see the comment above
about spltty() not blocking networking software interrupts...)

If you think that could be a problem, as a test, you might want to set
things up in i386/isa/isa_machdep.c so that the setting of any
hardware interrupt mask blocks out all software interrupts, by
changing the code:

        imask[IPL_BIO] |= SIR_CLOCKMASK;
        imask[IPL_NET] |= SIR_NETMASK;
        imask[IPL_TTY] |= SIR_TTYMASK;
        imask[IPL_CLOCK] |= SIR_CLOCKMASK;

so that it ands all of the SIR_.*MASKs into each imask[] element.
(SIR_NETMASK and SIR_TTYMASK already include SIR_CLOCKMASK.)

The fact that there are multiple 'levels' of software interrupt
(e.g. a networking software interrupt can happen while softclock is
running) _is_ kosher, and in keeping with the way software interrupts
were done on the VAX.  (i'm not sure if it's in keeping with BSD's
_ordering_ of software interrupt levels on the VAX, though... however,
having splsoftclock() being the least of them all makes sense.)


> 6. MGET, MFREE, etc., can be used at any spl level.

almost, but not quite, true.  MGET, MFREE, etc., can be called at any
spl level <= splimp.  You _can't_ call them if you're at a level
higher than splimp(), because they might lower the IPL on certain
processors.  (As far as i know, this isn't the case on the x86,
because the interrupt handling is bitmask-based, but would be a
problem on most other ports.)



chris