add missing wakeups in the cases of lock failure.

from Stephan Uphoff, FreeBSD PR/69964.

(http://www.freebsd.org/cgi/query-pr.cgi?pr=69964)
> 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 loc
> 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,
> or a signal (if lock priority includes PCATCH .. don't think this is used).
This commit is contained in:
yamt 2004-08-04 10:37:08 +00:00
parent 64a063e68b
commit 1e4aff5d38
1 changed files with 8 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_lock.c,v 1.82 2004/08/04 01:16:06 yamt Exp $ */
/* $NetBSD: kern_lock.c,v 1.83 2004/08/04 10:37:08 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.82 2004/08/04 01:16:06 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.83 2004/08/04 10:37:08 yamt Exp $");
#include "opt_multiprocessor.h"
#include "opt_lockdebug.h"
@ -718,8 +718,10 @@ lockmgr(__volatile struct lock *lkp, u_int flags,
lkp->lk_flags |= LK_WANT_UPGRADE;
error = acquire(&lkp, &s, extflags, 0, LK_SHARE_NONZERO);
lkp->lk_flags &= ~LK_WANT_UPGRADE;
if (error)
if (error) {
WAKEUP_WAITER(lkp);
break;
}
lkp->lk_flags |= LK_HAVE_EXCL;
SETHOLDER(lkp, pid, lid, cpu_id);
#if defined(LOCKDEBUG)
@ -787,8 +789,10 @@ lockmgr(__volatile struct lock *lkp, u_int flags,
error = acquire(&lkp, &s, extflags, 0,
LK_HAVE_EXCL | LK_WANT_UPGRADE | LK_SHARE_NONZERO);
lkp->lk_flags &= ~LK_WANT_EXCL;
if (error)
if (error) {
WAKEUP_WAITER(lkp);
break;
}
lkp->lk_flags |= LK_HAVE_EXCL;
SETHOLDER(lkp, pid, lid, cpu_id);
#if defined(LOCKDEBUG)