Date: Tue, 9 Sep 2008 15:38:08 -0400 From: John Baldwin <jhb@freebsd.org> To: freebsd-hackers@freebsd.org Cc: Marc =?iso-8859-1?q?L=F6rner?= <marc.loerner@hob.de> Subject: Re: question on asymmetric mtx_[un]lock_sleep Message-ID: <200809091538.08716.jhb@freebsd.org> In-Reply-To: <200809041400.04575.marc.loerner@hob.de> References: <200809041400.04575.marc.loerner@hob.de>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday 04 September 2008 08:00:04 am Marc L=F6rner wrote: > Hello, > I just read through the code of mutexes and turnstiles > and it seems to me that _mtx_lock_sleep and _mtx_unlock_sleep > are some kind of asymmetric when turning SMP and adaptive mutexes > on in kernel-configuration. >=20 > On locking the mutex, we try to "quick" obtain the lock. > If we can't do this, we look, whether some other thread, that's running, > holds the lock and spin until either lock is freed or thread is not runni= ng=20 > anymore. In that case we try again to obtain the lock "quick". > If the thread only stopped running but still holds the lock, we use=20 turnstiles > to wake us up, when the thread unlocks the mutex. > =3D> That seems to be fine and quite symmetric with _mtx_unlock_sleep!! >=20 > But if we're spinning and the other thread gave the mutex free,=20 > we quick-lock the mutex and don't set up a turnstile. >=20 > Now on mtx_unlock_sleep: > - in FreeBSD6/until revision 1.200 turnstiles were tested on existence. > =3D> if turnstile_lookup return NULL we only released the lock quick. >=20 > - But now, it's never tested if turnstile exists instead we broadcast/wak= eup > all threads pending on the turnstile. If this turnstile is NULL =3D> we= =20 access > wrong memory. >=20 > Now my question is: Why can we be sure (in new source) that turnstile_loo= kup=20 > always returns a valid pointer to an turnstile and can use returned point= er=20 > to call turnstile_broadcast? Am I missing something? >=20 > Because it seems that following scenario may occur: > - on locking same scenario as above (=3D> thread1 now holds the lock) > - thread1 is put off the runqueue > - thread2 now tries to quick unlock mutex and sees that thread1 holds it = =3D>=20 > call to mtx_unlock_sleep > - now we try to use turnstile-mechanism and call turnstile_lookup =3D> re= turns=20 > NULL because no thread waits for wakeup =3D> we call turnstile_broadcast = and=20 > crash. Newer locks don't set the CONTESTED flag unless they are actually going to = go=20 to sleep. If they succeed in setting CONTESTED or it is already set when=20 they test for it, then they will block on the turnstile. The turnstile cha= in=20 lock will prevent a concurrent unlock from grabbing the turnstile until the= =20 blocking thread is fully asleep. =2D-=20 John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200809091538.08716.jhb>