Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Oct 1998 02:55:30 +0200 (CEST)
From:      Tor Egge <tegge@not.fast.no>
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   kern/8416: vm_fault might deadlock when locking backing store vnode
Message-ID:  <199810230055.CAA10512@not.fast.no>

next in thread | raw e-mail | index | archive | help

>Number:         8416
>Category:       kern
>Synopsis:       vm_fault might deadlock when locking backing store vnode
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 22 18:00:00 PDT 1998
>Last-Modified:
>Originator:     Tor Egge
>Organization:
Fast Search & Transfer ASA
>Release:        FreeBSD 3.0-CURRENT i386
>Environment:

FreeBSD not.fast.no 3.0-CURRENT FreeBSD 3.0-CURRENT #1: Fri Oct 23 00:39:19 CEST 1998     root@not.fast.no:/usr/src/sys/compile/NOT  i386

>Description:

A system I manage recently hung due to a user having used the ls command while
a grep process was running.

The grep program was GNU grep version 2.1, which optimizes reads by
using mmap.  The final fragment is retrieved using read.

If, during the read(), another process attempts to obtain an exclusive
lock on the vnode (e.g. via the lstat() system call performed by ls),
vm_fault() blocks when attempting to obtain a second shared lock
on the vnode (vn_read obtained the first shared lock).  Deadlock.

#0  mi_switch () at ../../kern/kern_synch.c:683
#1  0xe013a0cd in tsleep (ident=0xe1c8ae00, priority=8, 
    wmesg=0xe01c75d3 "inode", timo=0) at ../../kern/kern_synch.c:452
#2  0xe0133673 in acquire (lkp=0xe1c8ae00, extflags=16777280, wanted=1792)
    at ../../kern/kern_lock.c:152
#3  0xe013383c in lockmgr (lkp=0xe1c8ae00, flags=16973889, 
    interlkp=0xeb081648, p=0xeae88e00) at ../../kern/kern_lock.c:207
#4  0xe0157720 in vop_stdlock (ap=0xeafc3c84) at ../../kern/vfs_default.c:201
#5  0xe01cfc95 in ufs_vnoperate (ap=0xeafc3c84)
    at ../../ufs/ufs/ufs_vnops.c:2291
#6  0xe0160593 in vn_lock (vp=0xeb0815e0, flags=16973889, p=0xeae88e00)
    at vnode_if.h:811
#7  0xe0159ecf in vget (vp=0xeb0815e0, flags=16908353, p=0xeae88e00)
    at ../../kern/vfs_subr.c:1284
#8  0xe01dfa3a in vnode_pager_lock (object=0xeb031660)
    at ../../vm/vnode_pager.c:933
#9  0xe01d268a in vm_fault (map=0xeae8d440, vaddr=554504192, 
    fault_type=3 '\003', fault_flags=8) at ../../vm/vm_fault.c:246
#10 0xe01f1bd2 in trap_pfault (frame=0xeafc3dd8, usermode=0)
    at ../../i386/i386/trap.c:760
#11 0xe01f186f in trap (frame={tf_es = 16, tf_ds = 16, tf_edi = 554504192, 
      tf_esi = -418590720, tf_ebp = -352567740, tf_isp = -352567808, 
      tf_ebx = 8192, tf_edx = -418590720, tf_ecx = 2048, tf_eax = 554512384, 
      tf_trapno = 12, tf_err = 2, tf_eip = -534838059, tf_cs = 8, 
      tf_eflags = 66054, tf_esp = 8192, tf_ss = -352567504})
    at ../../i386/i386/trap.c:399
#12 0xe01f04d5 in generic_copyout ()
#13 0xe01c8053 in ffs_read (ap=0xeafc3eec) at ../../ufs/ufs/ufs_readwrite.c:204
#14 0xe016004d in vn_read (fp=0xe1ce69c0, uio=0xeafc3f30, cred=0xe1cf8200)
    at vnode_if.h:303
#15 0xe01409fd in read (p=0xeae88e00, uap=0xeafc3f84)
    at ../../kern/sys_generic.c:121
#16 0xe01f2453 in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi = -541076236, 
      tf_esi = 2, tf_ebp = -541076280, tf_isp = -352567340, 
      tf_ebx = -541076224, tf_edx = 0, tf_ecx = 0, tf_eax = 3, tf_trapno = 12, 
      tf_err = 2, tf_eip = 554187896, tf_cs = 31, tf_eflags = 531, 
      tf_esp = -541076412, tf_ss = 39}) at ../../i386/i386/trap.c:1038
#17 0xe01e6e4c in Xint0x80_syscall ()
#18 0x8048519 in ?? ()


>How-To-Repeat:

>Fix:
>Audit-Trail:
>Unformatted:
>Workaround: 

Allow vm_fault to obtain a shared lock on the vnode even though an exclusive
lock has been requested (but not obtained) by a different process.

Index: kern_lock.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_lock.c,v
retrieving revision 1.19
diff -u -r1.19 kern_lock.c
--- kern_lock.c	1998/04/17 04:53:44	1.19
+++ kern_lock.c	1998/10/22 22:34:21
@@ -203,6 +204,12 @@
 
 	case LK_SHARED:
 		if (lkp->lk_lockholder != pid) {
+			if ((lkp->lk_flags & LK_SHARE_NONZERO) != 0 &&
+			    (flags & LK_CANRECURSE) != 0) {
+				sharelock(lkp, 1);
+				COUNT(p, 1);
+				break;
+			}
 			error = acquire(lkp, extflags,
 				LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE);
 			if (error)



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199810230055.CAA10512>