From owner-freebsd-bugs Tue Feb 4 21:39:02 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id VAA05032 for bugs-outgoing; Tue, 4 Feb 1997 21:39:02 -0800 (PST) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id VAA05019; Tue, 4 Feb 1997 21:38:50 -0800 (PST) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.3/8.6.9) id QAA21597; Wed, 5 Feb 1997 16:29:28 +1100 Date: Wed, 5 Feb 1997 16:29:28 +1100 From: Bruce Evans Message-Id: <199702050529.QAA21597@godzilla.zeta.org.au> To: bugs@freebsd.org Subject: ipl not preserved by cpu_switch() Cc: davidg@freebsd.org, peter@freebsd.org Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk cpu_switch() doesn't preserve the ipl. This seems to be fairly harmless. It only makes a difference for some cases involving stopped processes. One case is easy to duplicate: run something under gdb, stop it with ^C, and then quit gdb. The stopped process usually exits immediately and calls exit1() at splhigh(). Bruce diff -c2 kern_synch.c~ kern_synch.c *** kern_synch.c~ Wed Jan 15 05:04:32 1997 --- kern_synch.c Tue Feb 4 11:30:13 1997 *************** *** 528,533 **** --- 527,552 ---- register struct rlimit *rlim; register long s, u; + int x; struct timeval tv; + /* + * XXX this spl is almost unnecessary. It is partly to allow for + * sloppy callers that don't do it (issignal() via CURSIG() is the + * main offender). It is partly to work around a bug in the i386 + * cpu_switch() (the ipl is not preserved). We ran for years + * without it. I think there was only a interrupt latency problem. + * The main caller, tlseep(), does an splx() a couple of instructions + * after calling here. The buggy caller, issignal(), usually calls + * here at spl0() and sometimes returns at splhigh(). The process + * then runs for a little too long at splhigh(). The ipl gets fixed + * when the process returns to user mode (or earlier). + * + * It would probably be better to always call here at spl0(). Callers + * are prepared to give up control to another process, so they must + * be prepared to be interrupted. The clock stuff here may not + * actually need splstatclock(). + */ + x = splstatclock(); + #ifdef DEBUG if (p->p_simple_locks) *************** *** 574,577 **** --- 593,597 ---- cpu_switch(p); microtime(&runtime); + splx(x); }