Subject: Re: Is the netBSD kernel Preemptible ?
To: NetBSD Performance Technical Discussion List <tech-perform@NetBSD.ORG>
From: David Laight <david@l8s.co.uk>
List: tech-perform
Date: 06/15/2002 10:59:06
> 1984, but still....
> 
> Some unrelated sections of ioctl() routines might make sense to run
> concurrently.  But you can only read or write to/from a device one CPU
> at a time, and you can only twiddle its registers from one CPU at a
> time!

Eh? What evidence do you base that presumption on?
The SMP ethernet driver (lance) driver I wrote would do concurrent
TX setup on multiple CPUs.  Locks were only taken for a few
instructions - eg grabbing a slot in the tx ring.
> 
> If early SMP Linux really did have one semaphore on the whole kernel
> (though I'm not sure that rumour is 100% true) then the networking stack
> would surely suffer since I suspect it is one place where careful use of
> semaphores on individual data structures could pay off big time.

One big sema4 gets you the SMP 'tick in the box' - probably beats
windoze on MP systems where only some apps can use the second cpu.
OTOH a single user (desktop) system doesn't often have a second
job lutking.....
> 
> > >The driver entry points are obviously very well known by the kernel.
> > >They're identical for all drivers.  Even in *BSD this part of the device
> > >driver API is _very_ well defined.  The kernel really cannot call a
> > >driver routine that it doesn't already know about!
> > 
> > Do you mean: open(), read(), write(), ioctl(), etc? What about routines 
> > which are not for user-space, e.g. routines used by these access points to 
> > do the grunt work?
> 
> You mean like the strategy() and interrupt routines and such?
> 
> If so then yes, and all those too.  For the SysVr3 Block and Character
> Interface they are: close(), init(), int(), ioctl(), open(), print(),
> proc(), read(), rint(), start(), strategy(), write(), and xint().
<snip> 
> 
> > Won't each driver need to lock/coordinate access?
> 
> Nope, not necessarily -- the system can put a separate semaphore around
> each individual call.  If I'm not mistaken this is already effectively
> done in NetBSD with simple_lock*() wrappers around the filesystem vnode
> operations.  (I've not really been following NetBSD/SMP very closely yet
> so I may be way off here!  ;-)

If you are doing this you have to use a single (or small number of)
global locks.  You don't know which internal data structures a
driver might access when entered to do a particular operation on a
particular device.
> 
> To quote Bach and Buroff from the Oct. 1984 BSTJ again:
> 
>     First drivers are locked before they are called.  Driver calls are
>     table driven via the bdevsw and cdevsw tables, and the drivers are
>     locaked and unlocked around the driver calls using driver semaphores
>     added to the tables.  Various methods of driver protection are
>     encoded based on system configuration [[ by which they mean MP
>     vs. AP ]].  The levels of protection vary from no protection
>     (protection is then hard-coded in the driver [[ driver is "MP-safe"
>     presumably]] ), to forcing the process to run on a particular
>     processor (useful in AP configurations where only on processor can
>     do the I/O), to locking per major or per minor device type.  Each
>     call to a driver routine is now preceded by a call to a driver lock
>     routine and followed by a call to a driver unlock routine.

Mmmmm  That seems to be talking about 'code locking' not 'data locking'
The fact that it is so old (1984) makes me think it was written
before any real SMP systems had been working.
> 
> They go on to describe changes necessary to make sleep() and wakeup()
> work without having to change their DKI specification -- and the fact
> that now sleep() and wakeup() are reduced to just DKI calls and that the
> rest of the kernel uses semaphores directly.

Why do that!  nought wrong with sleep and wakeup - just implemement them
MP safe - its not hard.

>      * An advanced scheduling model.  Multiple driver instances can be
>        run in parallel on multiple processors with no lock management
>        performed by the driver.  Free paralllism and scalability!

Seems fine by me.

Actually writing MP safe drivers isn't hard.
Indeed making them MP ssafe will make you think about the interrupt
interractions and get those right as well.
Unfortunately loads of device drivers have holes you can drive a 
bus though sideways.

	David


	David

-- 
David Laight: david@l8s.co.uk