From owner-freebsd-hackers@FreeBSD.ORG Tue Sep 9 21:04:44 2008 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3F643106564A for ; Tue, 9 Sep 2008 21:04:44 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from server.baldwin.cx (bigknife-pt.tunnel.tserv9.chi1.ipv6.he.net [IPv6:2001:470:1f10:75::2]) by mx1.freebsd.org (Postfix) with ESMTP id B54F68FC1F for ; Tue, 9 Sep 2008 21:04:43 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from localhost.corp.yahoo.com (john@localhost [IPv6:::1]) (authenticated bits=0) by server.baldwin.cx (8.14.2/8.14.2) with ESMTP id m89L4CIi008827; Tue, 9 Sep 2008 17:04:37 -0400 (EDT) (envelope-from jhb@freebsd.org) From: John Baldwin To: freebsd-hackers@freebsd.org Date: Tue, 9 Sep 2008 15:38:08 -0400 User-Agent: KMail/1.9.7 References: <200809041400.04575.marc.loerner@hob.de> In-Reply-To: <200809041400.04575.marc.loerner@hob.de> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200809091538.08716.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (server.baldwin.cx [IPv6:::1]); Tue, 09 Sep 2008 17:04:37 -0400 (EDT) X-Virus-Scanned: ClamAV 0.93.1/8162/Thu Sep 4 12:38:45 2008 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-2.6 required=4.2 tests=AWL,BAYES_00,NO_RELAYS autolearn=ham version=3.1.3 X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on server.baldwin.cx Cc: Marc =?iso-8859-1?q?L=F6rner?= Subject: Re: question on asymmetric mtx_[un]lock_sleep X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Sep 2008 21:04:44 -0000 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