Wanted: spl()ing checkers

Darryl Baker dpb at laidbak.UUCP
Wed Oct 9 04:55:07 AEST 1985


In article <5237 at elsie.UUCP> ado at elsie.UUCP (Arthur David Olson) writes:
>The 4.2bsd version of the kernel function "bflush" calls "spl6",
>goes through some gyrations, and eventually may call one of the disk "strategy"
>functions.  One of these in particular, "hpstrategy", calls "spl5".
>
>Now it seems to me that theoretically the spl5 call when things are chugging
>along at priority level 6 is a no-no--although in this case there doesn't seem
>to be any bad effect in practice.
>
>And so some questions to all you wizards:
>
>1.	Should "bflush" actually be doing a "spl5" call?
	Yes, there is nothing done at clock interrupt time that effects
	bflush.
>2.	Should "hpstrategy" actually be doing a "spl6" call?
	I don't know.
>3.	Should "bflush" be doing a "splx(s)" call (to restore the processor
>	level to its entry value) before calling the disk strategy function?
	No, it can be called at user level (spl0) and interrupt routines will
	muck with buffers.
>4.	Should spl4, spl5, spl6, and spl7 check to ensure that the priority
>	level is being raised before changing the priority level?
	Maybe, this is a matter of taste.
>--
You have some good thoughts but missed the point that the bflush algorithm
is terrible especially if you have a great (>256) number of buffers. I will
include a suggestion for a different bflush algorithm. Warning I have not
yet tested this on a 4.2 BSD System but I have seen something like this
used on a System V System. The difference in the two alorithm is that the
current one finds one buffer to write for each pass through the freelist
until it makes it all the way through and the one I'm suggesting writes all
the buffers it can find in the headers for each pass until it makes one 
complete pass without finding one to write.

/*
 * make sure all write-behind blocks
 * on dev (or NODEV for all)
 * are flushed out.
 * (from umount and update)
 */
bflush(dev)
register dev_t dev;
{
	register struct buf *bp;
	register int bufferwritten;
	register int s;

        s = spl5();
	do {
		bufferwritten = FALSE;
        	for (bp = buf ; bp < &buf[nbuf]; bp++)
        	{
	 		spl5();  /* needed because drivers may mung the spl */
				 /* even though they shouldn't */
			if (	(bp->b_flags&B_DELWRI)
				&& (dev == NODEV || dev==bp->b_dev)
				&& ((bp->b_flags&B_BUSY) != B_BUSY))
                	{
				bp->b_flags |= B_ASYNC;
				notavail(bp);	/* This macro should also be
						 * modified to do an spl5 not
						 * spl6 */
				bufferwritten = TRUE;
				bwrite(bp);
			}
                }
        } while(bufferwritten);
        splx(s);
}



-- 
				from the sleepy terminal of
				Darryl Baker
				[ihnp4!]laidbak!dpb



More information about the Comp.unix.wizards mailing list