diff options
author | Mateusz Guzik <mjg@FreeBSD.org> | 2015-06-10 09:34:50 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2015-06-10 09:34:50 +0000 |
commit | 153cc61b54072dc9106a92f0ce23b5e854939290 (patch) | |
tree | d834ae899ad9b6407dd2feaa458a6f70fdd51cd8 /sys/kern | |
parent | 5cd7a4f76c66ece18de6a1fddb94a46f4ffc2352 (diff) | |
download | src-153cc61b54072dc9106a92f0ce23b5e854939290.tar.gz src-153cc61b54072dc9106a92f0ce23b5e854939290.zip |
fd: use atomics to manage fd_refcnt and fd_holcnt
This gets rid of fdesc_mtx.
Notes
Notes:
svn path=/head/; revision=284211
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_descrip.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 78483962eccc..c2bd0cad7b22 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1809,8 +1809,8 @@ fdinit(struct filedesc *fdp, bool prepfiles) /* Create the file descriptor table. */ FILEDESC_LOCK_INIT(newfdp); - newfdp->fd_refcnt = 1; - newfdp->fd_holdcnt = 1; + refcount_init(&newfdp->fd_refcnt, 1); + refcount_init(&newfdp->fd_holdcnt, 1); newfdp->fd_cmask = CMASK; newfdp->fd_map = newfdp0->fd_dmap; newfdp->fd_lastfile = -1; @@ -1852,24 +1852,19 @@ fdhold(struct proc *p) { struct filedesc *fdp; - mtx_lock(&fdesc_mtx); + PROC_LOCK_ASSERT(p, MA_OWNED); fdp = p->p_fd; if (fdp != NULL) - fdp->fd_holdcnt++; - mtx_unlock(&fdesc_mtx); + refcount_acquire(&fdp->fd_holdcnt); return (fdp); } static void fddrop(struct filedesc *fdp) { - int i; if (fdp->fd_holdcnt > 1) { - mtx_lock(&fdesc_mtx); - i = --fdp->fd_holdcnt; - mtx_unlock(&fdesc_mtx); - if (i > 0) + if (refcount_release(&fdp->fd_holdcnt) == 0) return; } @@ -1884,9 +1879,7 @@ struct filedesc * fdshare(struct filedesc *fdp) { - FILEDESC_XLOCK(fdp); - fdp->fd_refcnt++; - FILEDESC_XUNLOCK(fdp); + refcount_acquire(&fdp->fd_refcnt); return (fdp); } @@ -2032,6 +2025,7 @@ retry: void fdescfree(struct thread *td) { + struct proc *p; struct filedesc0 *fdp0; struct filedesc *fdp; struct freetable *ft, *tft; @@ -2040,31 +2034,29 @@ fdescfree(struct thread *td) struct vnode *cdir, *jdir, *rdir; int i; - fdp = td->td_proc->p_fd; + p = td->td_proc; + fdp = p->p_fd; MPASS(fdp != NULL); #ifdef RACCT if (racct_enable) { - PROC_LOCK(td->td_proc); - racct_set(td->td_proc, RACCT_NOFILE, 0); - PROC_UNLOCK(td->td_proc); + PROC_LOCK(p); + racct_set(p, RACCT_NOFILE, 0); + PROC_UNLOCK(p); } #endif if (td->td_proc->p_fdtol != NULL) fdclearlocks(td); - mtx_lock(&fdesc_mtx); - td->td_proc->p_fd = NULL; - mtx_unlock(&fdesc_mtx); + PROC_LOCK(p); + p->p_fd = NULL; + PROC_UNLOCK(p); - FILEDESC_XLOCK(fdp); - i = --fdp->fd_refcnt; - if (i > 0) { - FILEDESC_XUNLOCK(fdp); + if (refcount_release(&fdp->fd_refcnt) == 0) return; - } + FILEDESC_XLOCK(fdp); cdir = fdp->fd_cdir; fdp->fd_cdir = NULL; rdir = fdp->fd_rdir; @@ -2884,7 +2876,9 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newdp) nrele = 0; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { + PROC_LOCK(p); fdp = fdhold(p); + PROC_UNLOCK(p); if (fdp == NULL) continue; FILEDESC_XLOCK(fdp); @@ -2979,9 +2973,13 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS) n = 0; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - if (p->p_state == PRS_NEW) + PROC_LOCK(p); + if (p->p_state == PRS_NEW) { + PROC_UNLOCK(p); continue; + } fdp = fdhold(p); + PROC_UNLOCK(p); if (fdp == NULL) continue; /* overestimates sparse tables. */ @@ -3008,8 +3006,8 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS) } xf.xf_pid = p->p_pid; xf.xf_uid = p->p_ucred->cr_uid; - PROC_UNLOCK(p); fdp = fdhold(p); + PROC_UNLOCK(p); if (fdp == NULL) continue; FILEDESC_SLOCK(fdp); |