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>