From owner-freebsd-current Mon Feb 25 18:24:15 2002 Delivered-To: freebsd-current@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id E6CAC37B400; Mon, 25 Feb 2002 18:24:07 -0800 (PST) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id NAA14508; Tue, 26 Feb 2002 13:23:52 +1100 Date: Tue, 26 Feb 2002 13:24:16 +1100 (EST) From: Bruce Evans X-X-Sender: To: Matthew Dillon Cc: Terry Lambert , Alfred Perlstein , Bosko Milekic , Seigo Tanimura , , John Baldwin Subject: Re: Patch for critical_enter()/critical_exit() & interrupt assembly revamp, please review! In-Reply-To: <200202252027.g1PKRKU52902@apollo.backplane.com> Message-ID: <20020226121245.F42820-100000@gamplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Mon, 25 Feb 2002, Matthew Dillon wrote: > Unless an unforseen problem arises, I am going to commit this tomorrow > and then start working on a cleanup patch. I have decided to Please wait for jhb's opinion on it. He seems to be offline again. I think he has plans and maybe even code for more code in critical_enter(). I think we don't agree with these plans, but they are just as valid as ours, and our versions undo many of his old changes. > I've looked at cleaning up cpu_critical_enter() & exit but its use > pollutes a number of MI source files: kern/kern_ktr.c, kern/subr_trap.c, > and kern/subr_witness.c are all misusing the functions. If these > functions can safely be changed to use critical_enter() and critical_exit() > I will rename the i386's cpu_critical*() functions into intr_disable() > and intr_restore() and then use the new names for internal i386 use. It is already one layer higher than the MD versions for i386's at least. The MD versions are disable_intr() (should be cli() to inhibit use in MI code), enable_intr() (should be sti() ...), read_eflags() and write_eflags(). cpu_critical*() is supposed to be the version with an MI interface and semantics, but one level lower than critical*(). In my version, critical*() essentially doesn't exist and cpu_critical*() is only used by fast interrupt handlers and hacks. The MI code in kern mainly depends on the MD function (with an MI interface and semantics) unpend(). > Is there any reason why the above uses of cpu_critical*() cannot be > changed to use standard critical*()? I believe we *always* have a > curthread structure to play with so it should just work. I think this would mostly work on i386's. It would more obviously work if td_critness were a per-cpu global and not in the thread struce. It essentially is a per-cpu global, but we optimize it by putting it in the thread struct. But ktr, especially, is very low level and should work in the middle of a thread switch. According to jake, it would only work on sparc64's if critical*() does something hardware-related. Lazy masking of interrupts is partly in hardware, so the hardware must be talked to to turn it on an off. On i386's, the masking is in software, so it can use td_critnest as a flag. The use of cpu_critical*() in subr_trap.c is a bit trickier/kludgier. We need to return from the interrupt handler atomically with clearing the lazy-masking flag. The hardware interrupt enable flag must be used for this on i386's. The code for this is logically: In ast: /* Prevent changes to flags while we are deciding if they are set. */ critical_enter(); while ((ke->ke_flags & (KEF_ASTPENDING | KEF_NEEDRESCHED)) != 0) { critical_exit(); ... /* As above. */ critical_enter(); } In doreti: /* * Must use MD code to prevent race window after critical_exit(). * We switch from lazy sofware masking using td_critnest (or * whatever critical_enter() uses) to hardware masking using cli. */ cli(); critical_exit(); ... iretd(); but this is optimized in -current by using cpu_critical*() instead of critical_enter*() in ast() and not doing the cli() and critical_exit() in doreti. This depends on cpu_critical_enter() being precisely cli(). Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message