[net.unix-wizards] spl5

jmoore@opus.UUCP (Jim Moore) (09/01/84)

Can any wizards out there explain the call to spl5() in the
4.2 exit code? The comment just says something like:

	(void) spl5();		/* hack for mem alloc race XXX */

I am trying to cut down on the amount of time that the kernel
stays at high interrupt priority, and this code maintains spl5
all the way into swtch(). Any one know what race condition this
interlock avoids?

As usual, I'll summarize upon request.

Thanks,
Jim Moore
NBI, Boulder Colorado
[ucbvax|hao|amd]!nbires!jmoore

jmoore@opus.UUCP (Jim Moore) (09/10/84)

Sorry if this request came across before, but our net feed was down
and I do not know if this message got out.

I am trying to cut down the amount of time that our 4.2 kernel runs
at high interrupt priority and I came across the following code in
kern_exit function exit():

	vrelpt(u.u_procp);
	vrelu(u.u_procp, 0);
	(void) spl5();		/* hack for mem alloc race XXX */

And similar code in vm_swap.c function swapout():

	(void) spl6();		/* hack memory interlock XXX */
	vrelu(p, 1);
	.
	.
	vrelpt(p);

I would like to know the reason for the interrupt lockout. In both
situations it is possible that the current process is running on
a kernel stack whose pages have been put on the free list. Does this
mean that someone is allocating memory in an interrupt routine?
A routine in the callout list? This would imply that the code in
kern_exit.c is wrong because the spl5() is called too late. Why is
one spl5() and the other spl6()? Are these pieces of code even related?

Oh, so many questions and if I receive answers I'll certainly forward
them to interested parties or summarize on request.

Many thanks,
Jim Moore, NBI, Boulder Colorado
[ucbvax|hao|amd]!nbires!jmoore

thomson@uthub.UUCP (Brian Thomson) (09/18/84)

In 4.2BSD a network interface may allocate page(s) of memory
for an incoming datagram during interrupt service.
So, at least an splimp() is necessary and should indeed be
done before (not after) the vrelu() in exit().
An spl6() isn't necessary because the callouts are done at softclock
interrupt time, which is a very low interrupt priority.
However, all is not rosy.
Note that exit() calls swtch(), which will remain on the current
kernel stack and drop the cpu priority to 0 in its idle loop.
Now an interface may interrupt, allocate part of the current
u area for mbuf or mcluster use, fill it with good stuff,
then wake up a process.  On return from the interrupt, swtch()
finds a runnable process and falls into resume(), which
cheerfully saves the current process context smack on top of
the newly gathered good stuff.

Cheer up, though, the scenario is even worse when ported to
processors that don't have a separate interrupt stack.
-- 
		    Brian Thomson,	    CSRI Univ. of Toronto
		    {linus,ihnp4,uw-beaver,floyd,utzoo}!utcsrgv!uthub!thomson