From owner-svn-src-head@FreeBSD.ORG Wed Sep 2 17:33:52 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 14BDB10656A7; Wed, 2 Sep 2009 17:33:52 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 038338FC14; Wed, 2 Sep 2009 17:33:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n82HXpxK002873; Wed, 2 Sep 2009 17:33:51 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n82HXpV6002870; Wed, 2 Sep 2009 17:33:51 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <200909021733.n82HXpV6002870@svn.freebsd.org> From: Attilio Rao Date: Wed, 2 Sep 2009 17:33:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r196772 - head/sys/kern X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Sep 2009 17:33:52 -0000 Author: attilio Date: Wed Sep 2 17:33:51 2009 New Revision: 196772 URL: http://svn.freebsd.org/changeset/base/196772 Log: Fix some bugs related to adaptive spinning: In the lockmgr support: - GIANT_RESTORE() is just called when the sleep finishes, so the current code can ends up into a giant unlock problem. Fix it by appropriately call GIANT_RESTORE() when needed. Note that this is not exactly ideal because for any interation of the adaptive spinning we drop and restore Giant, but the overhead should be not a factor. - In the lock held in exclusive mode case, after the adaptive spinning is brought to completition, we should just retry to acquire the lock instead to fallthrough. Fix that. - Fix a style nit In the sx support: - Call GIANT_SAVE() before than looping. This saves some overhead because in the current code GIANT_SAVE() is called several times. Tested by: Giovanni Trematerra Modified: head/sys/kern/kern_lock.c head/sys/kern/kern_sx.c Modified: head/sys/kern/kern_lock.c ============================================================================== --- head/sys/kern/kern_lock.c Wed Sep 2 16:47:10 2009 (r196771) +++ head/sys/kern/kern_lock.c Wed Sep 2 17:33:51 2009 (r196772) @@ -467,7 +467,10 @@ __lockmgr_args(struct lock *lk, u_int fl /* * If the owner is running on another CPU, spin until * the owner stops running or the state of the lock - * changes. + * changes. We need a double-state handle here + * because for a failed acquisition the lock can be + * either held in exclusive mode or shared mode + * (for the writer starvation avoidance technique). */ if (LK_CAN_ADAPT(lk, flags) && (x & LK_SHARE) == 0 && LK_HOLDER(x) != LK_KERNPROC) { @@ -491,8 +494,10 @@ __lockmgr_args(struct lock *lk, u_int fl while (LK_HOLDER(lk->lk_lock) == (uintptr_t)owner && TD_IS_RUNNING(owner)) cpu_spinwait(); + GIANT_RESTORE(); + continue; } else if (LK_CAN_ADAPT(lk, flags) && - (x & LK_SHARE) !=0 && LK_SHARERS(x) && + (x & LK_SHARE) != 0 && LK_SHARERS(x) && spintries < alk_retries) { if (flags & LK_INTERLOCK) { class->lc_unlock(ilk); @@ -511,6 +516,7 @@ __lockmgr_args(struct lock *lk, u_int fl break; cpu_spinwait(); } + GIANT_RESTORE(); if (i != alk_loops) continue; } @@ -704,6 +710,8 @@ __lockmgr_args(struct lock *lk, u_int fl while (LK_HOLDER(lk->lk_lock) == (uintptr_t)owner && TD_IS_RUNNING(owner)) cpu_spinwait(); + GIANT_RESTORE(); + continue; } else if (LK_CAN_ADAPT(lk, flags) && (x & LK_SHARE) != 0 && LK_SHARERS(x) && spintries < alk_retries) { @@ -727,6 +735,7 @@ __lockmgr_args(struct lock *lk, u_int fl break; cpu_spinwait(); } + GIANT_RESTORE(); if (i != alk_loops) continue; } Modified: head/sys/kern/kern_sx.c ============================================================================== --- head/sys/kern/kern_sx.c Wed Sep 2 16:47:10 2009 (r196771) +++ head/sys/kern/kern_sx.c Wed Sep 2 17:33:51 2009 (r196772) @@ -531,13 +531,13 @@ _sx_xlock_hard(struct sx *sx, uintptr_t continue; } } else if (SX_SHARERS(x) && spintries < asx_retries) { + GIANT_SAVE(); spintries++; for (i = 0; i < asx_loops; i++) { if (LOCK_LOG_TEST(&sx->lock_object, 0)) CTR4(KTR_LOCK, "%s: shared spinning on %p with %u and %u", __func__, sx, spintries, i); - GIANT_SAVE(); x = sx->sx_lock; if ((x & SX_LOCK_SHARED) == 0 || SX_SHARERS(x) == 0)