From owner-svn-src-stable@freebsd.org Sat Dec 31 12:06:29 2016 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 07538C99EA0; Sat, 31 Dec 2016 12:06:29 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D5DAE15D5; Sat, 31 Dec 2016 12:06:28 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBVC6Sua067651; Sat, 31 Dec 2016 12:06:28 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBVC6RVU067643; Sat, 31 Dec 2016 12:06:27 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <201612311206.uBVC6RVU067643@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Sat, 31 Dec 2016 12:06:27 +0000 (UTC) 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 X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 31 Dec 2016 12:06:29 -0000 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);