Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Mar 2001 00:46:46 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        Matthew Jacob <mjacob@feral.com>, arch@FreeBSD.org
Subject:   Re: 'final' man pages
Message-ID:  <Pine.BSF.4.21.0103182337250.28547-100000@besplex.bde.org>
In-Reply-To: <XFMail.010318001205.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 18 Mar 2001, John Baldwin wrote:

> On 18-Mar-01 Matthew Jacob wrote:
> > Bruce- the following paragrahph is really hard to parse. I *think* you're
> > saying that we cannot guarantee nesting. That's a fair addition. Anything
> > else?
> 
> Hmm, as long as you pair state changes with restores you can handle nesting in
> the same way that spl's did, i.e.:
> 
>         x = intr_disable()
>         ...
>                 y = intr_disable()
>                 ....
>                 restore_intr(y)
>         ....
>         restore_intr(x)
> 
> will DTRT and not enable interrupts until after the second restore_intr().
> You do have to pair them up much like lock acquire/releases.

The problem is if interrupts are controlled by masks.  A lower priority
interrupt may occur while the above code is running (unless you dumb down
the masks a little to give levels).  The handler for this interrupt must
keep it disabled and not proceed far before continuing with the above
code (since the above code has higher priority).  This invalidates x and
y if x and y contain the mask.

> >>  Some cases need to be handled like ithread priorities: a handler
> >> for a high priority interrupt may have to yield to the handler for a
> >> lower priority interrupt to contest a lock.  This requires some non-nested
> >> handling of interrupt states.  I discussed this with John (jhb).  He was
> >> more pessimistic about it than me.
> 
> If a machine supports an external mechanism for disabling interrupts such as a
> PIC mask, then we can simply disable individual interrupts that way until the
> ithread associated with an interrupt source completes.  Note that we only

And this is what we do on i386's.

> really need to do this for level-triggered interrupts.  If we don't have this
> available and are forced to (ab)use the CPU interrupt level to mask interrupts,
> then we instead disable all other device interrupts on this CPU when an
> interrupt comes in until the associated ithread finishes.

We should disable precisely all the interrupts with the same or lower
priority while running the ithread.

> >>  I think things currently work on
> >> i386's because the interrupt state isn't all actually returned by
> >> save_intr() or restored by restore_intr().  Most of the state is in the
> >> ICU or APIC, and we depend on this because the state is a mask and not
> >> a level.  Priority propagation is more complicated because low priority
> >> interrupts aren't masked while high priority ones are being handled; we
> >> let them occur and then mask them.  If we didn't have the global state
> >> in the ICU/APIC, then we would have to adjust the saved state in various
> >> stack frames, but this is too hard.  OTOH, on alphas the interrupt state
> >> is controlled by a level and not a mask, so lower priority interrupts
> >> can't occur and I think nested handling of interrupt states works right
> >> provided ithread priorities work right.  Only the case where the interrupt
> >> state is a mask and is all returned by save_intr() is broken, and we don't
> >> support any machines that require that.
> 
> Actually, all device I/O interrupts on the alpha are at the same level, so they
> aren't split across multiple levels.

I didn't know that the alpha was that braindamaged :-).  alpha_cpu.h actually
gives 2 levels of device interrupts, ALPHA_PSL_IPL_CLOCK for clocks and
ALPHA_PSL_IPL_IO for other devices.

> Also, we lower the IPL back to 0 before
> running an ithread, so that only the actual interrupt stack that schedules an
> ithread to run runs at a raised IPL.

This is a bug.  In general, we can't lower the IPL below the level
needed to mask the interrupt that we're handling, because level-triggered
interrupts will repeat endlessly.  I'm not sure why this isn't fatal
for alphas.  It may be handled by "lazy interrupt masking" -- let the
interrupt repeat and mask it properly on the first repetition so that
it won't repeat again.

Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0103182337250.28547-100000>