Date: Thu, 19 Sep 96 09:26:42 EDT From: "Gordon W. Ross" <gwr@mc.com> To: michaelh@cet.co.jp Cc: freebsd-hackers@FreeBSD.ORG, tech-kern@netbsd.org Subject: Re: spl models and smp (was Re: Some interesting papers on BSD ...) Message-ID: <9609191326.AA03526@bach> In-Reply-To: <Pine.SV4.3.93.960919104629.12500A-100000@parkplace.cet.co.jp> (message from Michael Hancock on Thu, 19 Sep 1996 10:59:37 %2B0900 (JST))
next in thread | previous in thread | raw e-mail | index | archive | help
> Date: Thu, 19 Sep 1996 10:59:37 +0900 (JST) > From: Michael Hancock <michaelh@cet.co.jp> > [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. */ kmutex_t driver_mutex; /* 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: */ mutex_enter(&driver_mutex); /* now have exclusive access to the object locked with this mutex. */ mutex_exit(&driver_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: */ cv_signal(&sp->condvar); 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? Gordon
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9609191326.AA03526>