Subject: Re: kern/36669: NetBSD 4.0_BETA2 crashes with "panic: lockmgr: locking against myself"
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Antti Kantee <pooka@cs.hut.fi>
List: netbsd-bugs
Date: 07/20/2007 15:50:02
The following reply was made to PR kern/36669; it has been noted by GNATS.

From: Antti Kantee <pooka@cs.hut.fi>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, netbsd-bugs@netbsd.org,
	tron@zhadum.org.uk
Subject: Re: kern/36669: NetBSD 4.0_BETA2 crashes with "panic: lockmgr: locking against myself"
Date: Fri, 20 Jul 2007 18:47:09 +0300

 Here's a shotgun-approach that makes the panic go away.  I really didn't
 think it through as to if it produces more problems than it solves.
 
 Index: kern/vfs_getcwd.c
 ===================================================================
 RCS file: /cvsroot/src/sys/kern/vfs_getcwd.c,v
 retrieving revision 1.35
 diff -p -u -r1.35 vfs_getcwd.c
 --- kern/vfs_getcwd.c	9 Feb 2007 21:55:32 -0000	1.35
 +++ kern/vfs_getcwd.c	20 Jul 2007 15:42:27 -0000
 @@ -258,7 +258,7 @@ unionread:
  		vput(tvp);
  		VREF(uvp);
  		*uvpp = uvp;
 -		vn_lock(uvp, LK_EXCLUSIVE | LK_RETRY);
 +		vn_lock(uvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  		goto unionread;
  	}
  #endif
 @@ -315,7 +315,7 @@ getcwd_getcache(struct vnode **lvpp, str
  	 */
  
  	VOP_UNLOCK(lvp, 0);
 -	error = vget(uvp, LK_EXCLUSIVE | LK_RETRY);
 +	error = vget(uvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  
  	/*
  	 * Verify that vget succeeded while we were waiting for the
 @@ -329,7 +329,7 @@ getcwd_getcache(struct vnode **lvpp, str
  		 * the hard way.
  		 */
  		*uvpp = NULL;
 -		vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY);
 +		vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  		*bpp = obp;
  		return -1;
  	}
 @@ -371,7 +371,7 @@ getcwd_common(struct vnode *lvp, struct 
  	 *	uvp is either NULL, or locked and held.
  	 */
  
 -	vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY);
 +	vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  	if (bufp)
  		bp = *bpp;
  
 @@ -418,7 +418,7 @@ getcwd_common(struct vnode *lvp, struct 
  				goto out;
  			}
  			VREF(lvp);
 -			error = vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY);
 +			error = vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  			if (error != 0) {
  				vrele(lvp);
  				lvp = NULL;
 Index: miscfs/procfs/procfs_vnops.c
 ===================================================================
 RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vnops.c,v
 retrieving revision 1.157
 diff -p -u -r1.157 procfs_vnops.c
 --- miscfs/procfs/procfs_vnops.c	24 May 2007 00:37:41 -0000	1.157
 +++ miscfs/procfs/procfs_vnops.c	20 Jul 2007 15:42:27 -0000
 @@ -1062,7 +1062,7 @@ procfs_lookup(v)
  		if (cnp->cn_flags & ISDOTDOT) {
  			VOP_UNLOCK(dvp, 0);
  			error = procfs_root(dvp->v_mount, vpp);
 -			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
 +			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  			return (error);
  		}
  
 @@ -1093,7 +1093,7 @@ procfs_lookup(v)
  			fvp = p->p_textvp;
  			/* We already checked that it exists. */
  			VREF(fvp);
 -			vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
 +			vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  			*vpp = fvp;
  			procfs_proc_unlock(p);
  			return (0);
 @@ -1120,7 +1120,7 @@ procfs_lookup(v)
  			VOP_UNLOCK(dvp, 0);
  			error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
  			    PFSproc, -1, p);
 -			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
 +			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  			procfs_proc_unlock(p);
  			return (error);
  		}
 @@ -1146,8 +1146,7 @@ procfs_lookup(v)
  
  			VREF(fvp);
  			FILE_UNUSE(fp, l);
 -			vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY |
 -			    (p == curproc ? LK_CANRECURSE : 0));
 +			vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
  			*vpp = fvp;
  			error = 0;
  			break;
 
 -- 
 Antti Kantee <pooka@iki.fi>                     Of course he runs NetBSD
 http://www.iki.fi/pooka/                          http://www.NetBSD.org/
     "la qualité la plus indispensable du cuisinier est l'exactitude"