svn commit: r284211 - in head/sys: kern sys

Mateusz Guzik mjg at FreeBSD.org
Wed Jun 10 09:34:52 UTC 2015


Author: mjg
Date: Wed Jun 10 09:34:50 2015
New Revision: 284211
URL: https://svnweb.freebsd.org/changeset/base/284211

Log:
  fd: use atomics to manage fd_refcnt and fd_holcnt
  
  This gets rid of fdesc_mtx.

Modified:
  head/sys/kern/kern_descrip.c
  head/sys/sys/filedesc.h

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Wed Jun 10 05:39:48 2015	(r284210)
+++ head/sys/kern/kern_descrip.c	Wed Jun 10 09:34:50 2015	(r284211)
@@ -1809,8 +1809,8 @@ fdinit(struct filedesc *fdp, bool prepfi
 
 	/* 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, stru
 	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);

Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h	Wed Jun 10 05:39:48 2015	(r284210)
+++ head/sys/sys/filedesc.h	Wed Jun 10 09:34:50 2015	(r284211)
@@ -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() */


More information about the svn-src-all mailing list