Subject: Re: spl models and smp (was Re: Some interesting papers on BSD ...)
To: None <firstname.lastname@example.org>
From: Gordon W. Ross <email@example.com>
Date: 09/19/1996 09:26:42
> Date: Thu, 19 Sep 1996 10:59:37 +0900 (JST)
> From: Michael Hancock <firstname.lastname@example.org>
> [Just going through some old mail]
> I was reviewing some spl and locking models for SMP. SVR4/MP combines
> locking primitives with spl and Solaris is completely redesigned to the
> implementation to use kernel threads instead for interrupts so it can use
> the same locking model as the rest of the code.
Actually, I'm pretty sure that's not quite true. Here is how it works.
The relevant parts of the interface are:
/* This is a mutex lock. It MIGHT lock out interrupts. */
/* Somewhere, during initialization (attach) you do this: */
mutex_init(&driver_mutex, "mcos", MUTEX_DRIVER, (void*)&driver_ibcookie);
/* Then, a section that needs atomic actions is wrapped with: */
/* now have exclusive access to the object locked with this mutex. */
/* now others may take the mutex lock. */
The way these block interrupts is: if the driver_ibcookie (which
was returned to you when you attached your interrupt handler) is
passed to mutex_init, rather than a null pointer, then anyone who
does a mutex_enter() on that mutex will raise their spl as needed
to block that interrupt, and then spin-wait. The spin-wait will
never have to actually spin unless there is another CPU that holds
the mutex. When we take the mutex from non-interrupt level, the
mutex_enter() will have raised the spl() such that we don't have
to worry about deadlocking against our own interrupt handler.
Also note that Solaris no longer supports sleep/wakeup in MP drivers.
Instead, you use these new functions:
/* Here is the equivalent to the old sleep() call: */
status = cv_timedwait_sig(&sp->condvar, &driver_mutex, abst);
/* Here is the equivalent to the old wakeup() call: */
Note that you MUST hold a mutex lock on some object that has both
the mutex and a condition variable, adn the cv_timedwait_sig()
does an atomic "block and release the mutex" while making you
non-runnable, and later does an atomic "resume and take mutex."
Interesting scheme, eh?