Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Dec 2016 12:06:27 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r310953 - in stable/11/sys: kern sys
Message-ID:  <201612311206.uBVC6RVU067643@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Sat Dec 31 12:06:27 2016
New Revision: 310953
URL: https://svnweb.freebsd.org/changeset/base/310953

Log:
  MFC r309893,r309929:
  
      vfs: add vrefact, to be used when the vnode has to be already active
  
      This allows blind increment of relevant counters which under contention
      is cheaper than inc-not-zero loops at least on amd64.
  
      Use it in some of the places which are guaranteed to see already active
      vnodes.
  
  ==
  
      vfs: use vrefact in getcwd and fchdir

Modified:
  stable/11/sys/kern/kern_descrip.c
  stable/11/sys/kern/kern_fork.c
  stable/11/sys/kern/vfs_cache.c
  stable/11/sys/kern/vfs_lookup.c
  stable/11/sys/kern/vfs_subr.c
  stable/11/sys/kern/vfs_syscalls.c
  stable/11/sys/sys/vnode.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/kern/kern_descrip.c
==============================================================================
--- stable/11/sys/kern/kern_descrip.c	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/kern/kern_descrip.c	Sat Dec 31 12:06:27 2016	(r310953)
@@ -318,11 +318,11 @@ pwd_ensure_dirs(void)
 	FILEDESC_XLOCK(fdp);
 	if (fdp->fd_cdir == NULL) {
 		fdp->fd_cdir = rootvnode;
-		VREF(rootvnode);
+		vrefact(rootvnode);
 	}
 	if (fdp->fd_rdir == NULL) {
 		fdp->fd_rdir = rootvnode;
-		VREF(rootvnode);
+		vrefact(rootvnode);
 	}
 	FILEDESC_XUNLOCK(fdp);
 }
@@ -1855,13 +1855,13 @@ fdinit(struct filedesc *fdp, bool prepfi
 	FILEDESC_SLOCK(fdp);
 	newfdp->fd_cdir = fdp->fd_cdir;
 	if (newfdp->fd_cdir)
-		VREF(newfdp->fd_cdir);
+		vrefact(newfdp->fd_cdir);
 	newfdp->fd_rdir = fdp->fd_rdir;
 	if (newfdp->fd_rdir)
-		VREF(newfdp->fd_rdir);
+		vrefact(newfdp->fd_rdir);
 	newfdp->fd_jdir = fdp->fd_jdir;
 	if (newfdp->fd_jdir)
-		VREF(newfdp->fd_jdir);
+		vrefact(newfdp->fd_jdir);
 
 	if (!prepfiles) {
 		FILEDESC_SUNLOCK(fdp);
@@ -2688,7 +2688,7 @@ _fgetvp(struct thread *td, int fd, int f
 		error = EINVAL;
 	} else {
 		*vpp = fp->f_vnode;
-		vref(*vpp);
+		vrefact(*vpp);
 	}
 	fdrop(fp, td);
 
@@ -2727,7 +2727,7 @@ fgetvp_rights(struct thread *td, int fd,
 		return (EINVAL);
 
 	*vpp = fp->f_vnode;
-	vref(*vpp);
+	vrefact(*vpp);
 	filecaps_copy(&fdp->fd_ofiles[fd].fde_caps, havecaps, true);
 
 	return (0);
@@ -3033,10 +3033,10 @@ pwd_chroot(struct thread *td, struct vno
 		}
 	}
 	oldvp = fdp->fd_rdir;
-	VREF(vp);
+	vrefact(vp);
 	fdp->fd_rdir = vp;
 	if (fdp->fd_jdir == NULL) {
-		VREF(vp);
+		vrefact(vp);
 		fdp->fd_jdir = vp;
 	}
 	FILEDESC_XUNLOCK(fdp);
@@ -3084,17 +3084,17 @@ mountcheckdirs(struct vnode *olddp, stru
 			continue;
 		FILEDESC_XLOCK(fdp);
 		if (fdp->fd_cdir == olddp) {
-			vref(newdp);
+			vrefact(newdp);
 			fdp->fd_cdir = newdp;
 			nrele++;
 		}
 		if (fdp->fd_rdir == olddp) {
-			vref(newdp);
+			vrefact(newdp);
 			fdp->fd_rdir = newdp;
 			nrele++;
 		}
 		if (fdp->fd_jdir == olddp) {
-			vref(newdp);
+			vrefact(newdp);
 			fdp->fd_jdir = newdp;
 			nrele++;
 		}
@@ -3103,13 +3103,13 @@ mountcheckdirs(struct vnode *olddp, stru
 	}
 	sx_sunlock(&allproc_lock);
 	if (rootvnode == olddp) {
-		vref(newdp);
+		vrefact(newdp);
 		rootvnode = newdp;
 		nrele++;
 	}
 	mtx_lock(&prison0.pr_mtx);
 	if (prison0.pr_root == olddp) {
-		vref(newdp);
+		vrefact(newdp);
 		prison0.pr_root = newdp;
 		nrele++;
 	}
@@ -3118,7 +3118,7 @@ mountcheckdirs(struct vnode *olddp, stru
 	TAILQ_FOREACH(pr, &allprison, pr_list) {
 		mtx_lock(&pr->pr_mtx);
 		if (pr->pr_root == olddp) {
-			vref(newdp);
+			vrefact(newdp);
 			pr->pr_root = newdp;
 			nrele++;
 		}
@@ -3445,17 +3445,17 @@ kern_proc_filedesc_out(struct proc *p,  
 	/* ktrace vnode */
 	tracevp = p->p_tracevp;
 	if (tracevp != NULL)
-		vref(tracevp);
+		vrefact(tracevp);
 	/* text vnode */
 	textvp = p->p_textvp;
 	if (textvp != NULL)
-		vref(textvp);
+		vrefact(textvp);
 	/* Controlling tty. */
 	cttyvp = NULL;
 	if (p->p_pgrp != NULL && p->p_pgrp->pg_session != NULL) {
 		cttyvp = p->p_pgrp->pg_session->s_ttyvp;
 		if (cttyvp != NULL)
-			vref(cttyvp);
+			vrefact(cttyvp);
 	}
 	fdp = fdhold(p);
 	PROC_UNLOCK(p);
@@ -3479,17 +3479,17 @@ kern_proc_filedesc_out(struct proc *p,  
 	FILEDESC_SLOCK(fdp);
 	/* working directory */
 	if (fdp->fd_cdir != NULL) {
-		vref(fdp->fd_cdir);
+		vrefact(fdp->fd_cdir);
 		export_vnode_to_sb(fdp->fd_cdir, KF_FD_TYPE_CWD, FREAD, efbuf);
 	}
 	/* root directory */
 	if (fdp->fd_rdir != NULL) {
-		vref(fdp->fd_rdir);
+		vrefact(fdp->fd_rdir);
 		export_vnode_to_sb(fdp->fd_rdir, KF_FD_TYPE_ROOT, FREAD, efbuf);
 	}
 	/* jail directory */
 	if (fdp->fd_jdir != NULL) {
-		vref(fdp->fd_jdir);
+		vrefact(fdp->fd_jdir);
 		export_vnode_to_sb(fdp->fd_jdir, KF_FD_TYPE_JAIL, FREAD, efbuf);
 	}
 	for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
@@ -3579,7 +3579,7 @@ export_vnode_for_osysctl(struct vnode *v
 {
 	int error;
 
-	vref(vp);
+	vrefact(vp);
 	FILEDESC_SUNLOCK(fdp);
 	export_vnode_to_kinfo(vp, type, 0, kif, KERN_FILEDESC_PACK_KINFO);
 	kinfo_to_okinfo(kif, okif);
@@ -3706,7 +3706,7 @@ kern_proc_cwd_out(struct proc *p,  struc
 	if (fdp->fd_cdir == NULL)
 		error = EINVAL;
 	else {
-		vref(fdp->fd_cdir);
+		vrefact(fdp->fd_cdir);
 		error = export_vnode_to_sb(fdp->fd_cdir, KF_FD_TYPE_CWD,
 		    FREAD, efbuf);
 	}

Modified: stable/11/sys/kern/kern_fork.c
==============================================================================
--- stable/11/sys/kern/kern_fork.c	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/kern/kern_fork.c	Sat Dec 31 12:06:27 2016	(r310953)
@@ -549,7 +549,7 @@ do_fork(struct thread *td, struct fork_r
 
 	/* Bump references to the text vnode (for procfs). */
 	if (p2->p_textvp)
-		vref(p2->p_textvp);
+		vrefact(p2->p_textvp);
 
 	/*
 	 * Set up linkage for kernel based threading.

Modified: stable/11/sys/kern/vfs_cache.c
==============================================================================
--- stable/11/sys/kern/vfs_cache.c	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/kern/vfs_cache.c	Sat Dec 31 12:06:27 2016	(r310953)
@@ -1122,9 +1122,9 @@ kern___getcwd(struct thread *td, char *b
 	fdp = td->td_proc->p_fd;
 	FILEDESC_SLOCK(fdp);
 	cdir = fdp->fd_cdir;
-	VREF(cdir);
+	vrefact(cdir);
 	rdir = fdp->fd_rdir;
-	VREF(rdir);
+	vrefact(rdir);
 	FILEDESC_SUNLOCK(fdp);
 	error = vn_fullpath1(td, cdir, rdir, tmpbuf, &bp, buflen);
 	vrele(rdir);

Modified: stable/11/sys/kern/vfs_lookup.c
==============================================================================
--- stable/11/sys/kern/vfs_lookup.c	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/kern/vfs_lookup.c	Sat Dec 31 12:06:27 2016	(r310953)
@@ -200,7 +200,7 @@ namei_handle_root(struct nameidata *ndp,
 		ndp->ni_pathlen--;
 	}
 	*dpp = ndp->ni_rootdir;
-	VREF(*dpp);
+	vrefact(*dpp);
 	return (0);
 }
 
@@ -321,7 +321,7 @@ namei(struct nameidata *ndp)
 	 */
 	FILEDESC_SLOCK(fdp);
 	ndp->ni_rootdir = fdp->fd_rdir;
-	VREF(ndp->ni_rootdir);
+	vrefact(ndp->ni_rootdir);
 	ndp->ni_topdir = fdp->fd_jdir;
 
 	/*
@@ -343,7 +343,7 @@ namei(struct nameidata *ndp)
 			startdir_used = 1;
 		} else if (ndp->ni_dirfd == AT_FDCWD) {
 			dp = fdp->fd_cdir;
-			VREF(dp);
+			vrefact(dp);
 		} else {
 			rights = ndp->ni_rightsneeded;
 			cap_rights_set(&rights, CAP_LOOKUP);
@@ -910,7 +910,7 @@ good:
 			vput(ndp->ni_dvp);
 		else
 			vrele(ndp->ni_dvp);
-		vref(vp_crossmp);
+		vrefact(vp_crossmp);
 		ndp->ni_dvp = vp_crossmp;
 		error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags,
 		    cnp->cn_flags), &tdp);

Modified: stable/11/sys/kern/vfs_subr.c
==============================================================================
--- stable/11/sys/kern/vfs_subr.c	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/kern/vfs_subr.c	Sat Dec 31 12:06:27 2016	(r310953)
@@ -2576,6 +2576,28 @@ vrefl(struct vnode *vp)
 	v_incr_usecount_locked(vp);
 }
 
+void
+vrefact(struct vnode *vp)
+{
+
+	CTR2(KTR_VFS, "%s: vp %p", __func__, vp);
+	if (__predict_false(vp->v_type == VCHR)) {
+		VNASSERT(vp->v_holdcnt > 0 && vp->v_usecount > 0, vp,
+		    ("%s: wrong ref counts", __func__));
+		vref(vp);
+		return;
+	}
+#ifdef INVARIANTS
+	int old = atomic_fetchadd_int(&vp->v_holdcnt, 1);
+	VNASSERT(old > 0, vp, ("%s: wrong hold count", __func__));
+	old = atomic_fetchadd_int(&vp->v_usecount, 1);
+	VNASSERT(old > 0, vp, ("%s: wrong use count", __func__));
+#else
+	refcount_acquire(&vp->v_holdcnt);
+	refcount_acquire(&vp->v_usecount);
+#endif
+}
+
 /*
  * Return reference count of a vnode.
  *

Modified: stable/11/sys/kern/vfs_syscalls.c
==============================================================================
--- stable/11/sys/kern/vfs_syscalls.c	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/kern/vfs_syscalls.c	Sat Dec 31 12:06:27 2016	(r310953)
@@ -754,7 +754,7 @@ sys_fchdir(td, uap)
 	if (error != 0)
 		return (error);
 	vp = fp->f_vnode;
-	VREF(vp);
+	vrefact(vp);
 	fdrop(fp, td);
 	vn_lock(vp, LK_SHARED | LK_RETRY);
 	AUDIT_ARG_VNODE1(vp);

Modified: stable/11/sys/sys/vnode.h
==============================================================================
--- stable/11/sys/sys/vnode.h	Sat Dec 31 12:03:25 2016	(r310952)
+++ stable/11/sys/sys/vnode.h	Sat Dec 31 12:06:27 2016	(r310953)
@@ -841,6 +841,7 @@ void	vput(struct vnode *vp);
 void	vrele(struct vnode *vp);
 void	vref(struct vnode *vp);
 void	vrefl(struct vnode *vp);
+void	vrefact(struct vnode *vp);
 int	vrefcnt(struct vnode *vp);
 void 	v_addpollinfo(struct vnode *vp);
 



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