From ups@tree.com  Tue Aug  3 21:25:12 2004
Return-Path: <ups@tree.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 6BF5216A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  3 Aug 2004 21:25:12 +0000 (GMT)
Received: from duchess.speedfactory.net (duchess.speedfactory.net [66.23.201.84])
	by mx1.FreeBSD.org (Postfix) with SMTP id 0435943D48
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  3 Aug 2004 21:25:12 +0000 (GMT)
	(envelope-from ups@tree.com)
Received: (qmail 19235 invoked by uid 89); 3 Aug 2004 21:25:11 -0000
Received: from duchess.speedfactory.net (66.23.201.84)
  by duchess.speedfactory.net with SMTP; 3 Aug 2004 21:25:11 -0000
Received: (qmail 19221 invoked by uid 89); 3 Aug 2004 21:25:11 -0000
Received: from unknown (HELO palm.tree.com) (66.23.216.49)
  by duchess.speedfactory.net with SMTP; 3 Aug 2004 21:25:11 -0000
Received: from palm.tree.com (localhost.tree.com [127.0.0.1])
	by palm.tree.com (8.12.10/8.12.10) with ESMTP id i73LPAfY048358
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 3 Aug 2004 17:25:10 -0400 (EDT)
	(envelope-from ups@palm.tree.com)
Received: (from ups@localhost)
	by palm.tree.com (8.12.10/8.12.10/Submit) id i73KuS6a014888;
	Tue, 3 Aug 2004 16:56:28 -0400 (EDT)
	(envelope-from ups)
Message-Id: <200408032056.i73KuS6a014888@palm.tree.com>
Date: Tue, 3 Aug 2004 16:56:28 -0400 (EDT)
From: Stephan Uphoff <ups@tree.com>
Reply-To: Stephan Uphoff <ups@tree.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] lockmgr can forget to unblock clients
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         69964
>Category:       kern
>Synopsis:       [patch] lockmgr can forget to unblock clients
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kan
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 03 21:30:19 GMT 2004
>Closed-Date:    Mon Jun 27 23:07:00 GMT 2005
>Last-Modified:  Mon Jun 27 23:07:00 GMT 2005
>Originator:     Stephan Uphoff
>Release:        FreeBSD 5.2.1-RELEASE-p5 i386
>Organization:
>Environment:
System: FreeBSD palm.tree.com 5.2.1-RELEASE-p5 FreeBSD 5.2.1-RELEASE-p5 #2: Fri May 7 20:06:27 EDT 2004 ups@palm.tree.com:/usr/obj/usr/src/sys/PALM i386


	
>Description:

The LK_WANT_EXCL and LK_WANT_UPGRADE bits act as mini-locks and can block
other threads.
Normally this is not a problem since the mini locks are upgraded to full locks
and the release of the locks will unblock the other threads.
However if a thread reset the bits without optaining a full lock
other threads are not awoken.
This can happens if obtaining the full lock fails because of a LK_SLEEPFAIL, LK_TIMELOCK
or a signal (if lock priority includes PCATCH .. don't think this is used).


>How-To-Repeat:
	
>Fix:


The following patch also includes the fix for kern/69934

diff -u -r1.73 kern_lock.c
--- kern_lock.c	23 Jul 2004 20:12:56 -0000	1.73
+++ kern_lock.c	3 Aug 2004 20:15:22 -0000
@@ -335,8 +335,12 @@
 			error = acquire(&lkp, extflags, LK_SHARE_NONZERO);
 			lkp->lk_flags &= ~LK_WANT_UPGRADE;
 
-			if (error)
-				break;
+			if (error) {
+			         if ((lkp->lk_flags & ( LK_WANT_EXCL | LK_WAIT_NONZERO)) == (LK_WANT_EXCL | LK_WAIT_NONZERO))
+			                   wakeup((void *)lkp);
+			         break;
+			}
+
 			lkp->lk_flags |= LK_HAVE_EXCL;
 			lkp->lk_lockholder = thr;
 			if (lkp->lk_exclusivecount != 0)
@@ -382,17 +386,20 @@
 		/*
 		 * Try to acquire the want_exclusive flag.
 		 */
-		error = acquire(&lkp, extflags, (LK_HAVE_EXCL | LK_WANT_EXCL));
+		error = acquire(&lkp, extflags,  LK_WANT_EXCL);
 		if (error)
 			break;
 		lkp->lk_flags |= LK_WANT_EXCL;
 		/*
 		 * Wait for shared locks and upgrades to finish.
 		 */
-		error = acquire(&lkp, extflags, LK_WANT_UPGRADE | LK_SHARE_NONZERO);
+		error = acquire(&lkp, extflags, LK_HAVE_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO);
 		lkp->lk_flags &= ~LK_WANT_EXCL;
-		if (error)
+		if (error) {
+			if (lkp->lk_flags & LK_WAIT_NONZERO)		
+			         wakeup((void *)lkp);
 			break;
+		}	
 		lkp->lk_flags |= LK_HAVE_EXCL;
 		lkp->lk_lockholder = thr;
 		if (lkp->lk_exclusivecount != 0)
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->kan 
Responsible-Changed-By: kan 
Responsible-Changed-When: Wed Aug 4 03:27:59 GMT 2004 
Responsible-Changed-Why:  
Grab is PR. I'll commit the patch after I have a chance to verify it 
more thoroughly in a day or two. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=69964 
State-Changed-From-To: open->closed 
State-Changed-By: kan 
State-Changed-When: Mon Jun 27 23:06:27 GMT 2005 
State-Changed-Why:  
The fix committed. Thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=69964 
>Unformatted:
