Skip site navigation (1)Skip section navigation (2)
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>