summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lock.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1999-03-12 03:09:29 +0000
committerjulian <julian@FreeBSD.org>1999-03-12 03:09:29 +0000
commit35ed86543837074d1d29e42be3c5833e7d86259a (patch)
treefd711020444efce3db2a73b8041ad8a741f93dfe /sys/kern/kern_lock.c
parentf27c95753fda68261265d744a5d8a9e59144d460 (diff)
downloadFreeBSD-src-35ed86543837074d1d29e42be3c5833e7d86259a.zip
FreeBSD-src-35ed86543837074d1d29e42be3c5833e7d86259a.tar.gz
This solves a deadlock that can occur when read()ing into a file-mmap()
space. When doing this, it is possible to for another process to attempt to get an exclusive lock on the vnode and deadlock the mmap/read combination when the uiomove() call tries to obtain a second shared lock on the vnode. There is still a potential deadlock situation with write()/mmap(). Submitted by: Matt Dillon <dillon@freebsd.org> Reviewed by: Luoqi Chen <luoqi@freebsd.org> Delimmitted by tag PRE_MATT_MMAP_LOCK and POST_MATT_MMAP_LOCK in kern/kern_lock.c kern/kern_subr.c
Diffstat (limited to 'sys/kern/kern_lock.c')
-rw-r--r--sys/kern/kern_lock.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index e832acf..1685b4c 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
- * $Id: kern_lock.c,v 1.22 1999/01/10 01:58:24 eivind Exp $
+ * $Id: kern_lock.c,v 1.23 1999/01/20 14:49:11 eivind Exp $
*/
#include "opt_lint.h"
@@ -205,9 +205,30 @@ debuglockmgr(lkp, flags, interlkp, p, name, file, line)
switch (flags & LK_TYPE_MASK) {
case LK_SHARED:
+ /*
+ * If we are not the exclusive lock holder, we have to block
+ * while there is an exclusive lock holder or while an
+ * exclusive lock request or upgrade request is in progress.
+ *
+ * However, if P_DEADLKTREAT is set, we override exclusive
+ * lock requests or upgrade requests ( but not the exclusive
+ * lock itself ).
+ */
if (lkp->lk_lockholder != pid) {
- error = acquire(lkp, extflags,
- LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE);
+ if (p->p_flag & P_DEADLKTREAT) {
+ error = acquire(
+ lkp,
+ extflags,
+ LK_HAVE_EXCL
+ );
+ } else {
+ error = acquire(
+ lkp,
+ extflags,
+ LK_HAVE_EXCL | LK_WANT_EXCL |
+ LK_WANT_UPGRADE
+ );
+ }
if (error)
break;
sharelock(lkp, 1);
OpenPOWER on IntegriCloud