summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2015-06-10 09:34:50 +0000
committermjg <mjg@FreeBSD.org>2015-06-10 09:34:50 +0000
commit34814bbfee78c6ce02f8dbfa7c2a287f529f832f (patch)
treed834ae899ad9b6407dd2feaa458a6f70fdd51cd8
parent73775f21e2a2f85b4ced45530b2eaf3d99f6a70d (diff)
downloadFreeBSD-src-34814bbfee78c6ce02f8dbfa7c2a287f529f832f.zip
FreeBSD-src-34814bbfee78c6ce02f8dbfa7c2a287f529f832f.tar.gz
fd: use atomics to manage fd_refcnt and fd_holcnt
This gets rid of fdesc_mtx.
-rw-r--r--sys/kern/kern_descrip.c52
-rw-r--r--sys/sys/filedesc.h4
2 files changed, 27 insertions, 29 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 7848396..c2bd0ca 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);
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index eca30ff..3fe61c8 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -83,8 +83,8 @@ struct filedesc {
int fd_lastfile; /* high-water mark of fd_ofiles */
int fd_freefile; /* approx. next free file */
u_short fd_cmask; /* mask for file creation */
- u_short fd_refcnt; /* thread reference count */
- u_short fd_holdcnt; /* hold count on structure + mutex */
+ int fd_refcnt; /* thread reference count */
+ int fd_holdcnt; /* hold count on structure + mutex */
struct sx fd_sx; /* protects members of this struct */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
int fd_holdleaderscount; /* block fdfree() for shared close() */
OpenPOWER on IntegriCloud