Date: Thu, 11 May 1995 23:06:22 -0700 From: William Maddox <maddox@CS.Berkeley.EDU> To: Tatu Ylonen <ylo@fx7.cs.hut.fi> Cc: freebsd-bugs@freefall.cdrom.com, maddox@redwood.CS.Berkeley.EDU Subject: Re: i386/395: CRITICAL PROBLEM: spl functions implemented incorrectly Message-ID: <199505120606.XAA13119@redwood.CS.Berkeley.EDU> In-Reply-To: Your message of "Thu, 11 May 1995 16:40:02 PDT." <199505112340.QAA19464@freefall.cdrom.com>
next in thread | previous in thread | raw e-mail | index | archive | help
You recently reported a bug in "spl.h" : > Spl functions (splbio, splclock, splhigh, splimp, splnet, > splsoftclock, splsofttty, splstatclock, spltty, spl0, splx) > are defined in /usr/src/sys/i386/include/spl.h as inline > functions that modify the ordinary variable cpl (extern > unsigned cpl in the same header). > > This means that the compiler has full knowledge about the > semantics, side-effects, and dependencies of these functions. > The compiler inlines these functions, and can mix (reorder) the > resulting code with other code in the function that calls the > spl function. ... >Fix: ... > i386/include/spl.h: > - Move the GENSPL macro and its uses, and spl0 and splx to > i386/386/sys_machdep.c. Edit the macro and functions to > make them normal non-static, non-inline functions. .... I think there is another potential problem lurking in spl.h, in the following: /* * ipending has to be volatile so that it is read every time it is accessed * in splx() and spl0(), but we don't want it to be read nonatomically when * it is changed. Pretending that ipending is a plain int happens to give * suitable atomic code for "ipending |= constant;". */ #define setdelayed() (*(unsigned *)&ipending |= loadandclear(&idelayed)) #define setsoftast() (*(unsigned *)&ipending |= SWI_AST_PENDING) #define setsoftclock() (*(unsigned *)&ipending |= SWI_CLOCK_PENDING) #define setsoftnet() (*(unsigned *)&ipending |= SWI_NET_PENDING) #define setsofttty() (*(unsigned *)&ipending |= SWI_TTY_PENDING) I assume that the remark above regarding "suitable atomic code" means that the bits are set in place in memory, using a single instruction. Just because GCC happens to do this today doesn't mean it will tomorrow. As the internal execution mechanisms of new-generation x86 processors become more heavily parallel and RISC-like, instruction sequences involving architecturally unnecessary register temporaries may turn out to be faster. I wouldn't bet on the stability of a compiler's choice of instructions in future releases, and I doubt that anyone is going to check this each time a new version of GCC is integrated into FreeBSD. I would suggest defining these functions as in-line assembly-language functions. In any case, this is the sort of thing that should be done in assembler, not C. --Bill
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199505120606.XAA13119>