Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Mar 2001 16:08:47 -0800 (PST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        arch@FreeBSD.org, Matthew Jacob <mjacob@feral.com>
Subject:   Re: 'final' man pages
Message-ID:  <XFMail.010318160847.jhb@FreeBSD.org>
In-Reply-To: <Pine.BSF.4.21.0103182337250.28547-100000@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 18-Mar-01 Bruce Evans wrote:
> 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.

They won't be the same masks.  Well, even if they are, you would just have
intr_disable() disable all interrupts, then no further interrupts can trigger
that might affect the masks.  The point of intr_disable() is that the masks
can't change because we can't be preempted.  Having an interrupt come in is
preemption, and this API explicitly prevents that.  Having
critcal_enter()/critical_exit() might be better names for this.

>> 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.

And alpha'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.

Errrm, what about a MP system that wires all interrupts to one processor (I
think some alphas may be this brain-damaged) we would want lower priority
interrupts to fire so that their threads would be scheduled and then picked up
by another CPU and run.  Ithread priorities will ensure that ithreads are
processed in the right order.  No hardware masking is needed.

>> 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.

Well, ALPHA_PSL_IPL_CLOCK is just for the CPU clock.  Other clock interrupts
suck as those from mcclock0 are at IPL_IO, and currently all threaded
interrupts on the alpha are at IPL_IO.

>> 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.

We mask the interrupts in the PIC just like on x86, otherwise a PCI interrupt
can cause problems because it is level triggered.  In theory we don't even need
to mask edge triggered interrupts at all as all that would happen is that the
ithread's it_need bit would get set again if it is already running.

> Bruce

-- 

John Baldwin <jhb@FreeBSD.org> -- http://www.FreeBSD.org/~jhb/
PGP Key: http://www.baldwin.cx/~john/pgpkey.asc
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

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?XFMail.010318160847.jhb>