Author: mjg
Date: Thu Jul 10 20:59:54 2014
New Revision: 268505
URL: http://svnweb.freebsd.org/changeset/base/268505

Log:
  Avoid relocking filedesc lock when closing fds during fdp destruction.
  
  Don't call bzero nor fdunused from fdfree for such cases. It would do
  unnecessary work and complain that the lock is not taken.
  
  MFC after:    1 week

Modified:
  head/sys/kern/kern_descrip.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Thu Jul 10 20:55:38 2014        
(r268504)
+++ head/sys/kern/kern_descrip.c        Thu Jul 10 20:59:54 2014        
(r268505)
@@ -294,18 +294,36 @@ fdunused(struct filedesc *fdp, int fd)
 
 /*
  * Free a file descriptor.
+ *
+ * Avoid some work if fdp is about to be destroyed.
  */
 static inline void
-fdfree(struct filedesc *fdp, int fd)
+_fdfree(struct filedesc *fdp, int fd, int last)
 {
        struct filedescent *fde;
 
        fde = &fdp->fd_ofiles[fd];
        filecaps_free(&fde->fde_caps);
+       if (last)
+               return;
        bzero(fde, sizeof(*fde));
        fdunused(fdp, fd);
 }
 
+static inline void
+fdfree(struct filedesc *fdp, int fd)
+{
+
+       _fdfree(fdp, fd, 0);
+}
+
+static inline void
+fdfree_last(struct filedesc *fdp, int fd)
+{
+
+       _fdfree(fdp, fd, 1);
+}
+
 /*
  * System calls on descriptors.
  */
@@ -2011,36 +2029,34 @@ fdescfree(struct thread *td)
 
        FILEDESC_XLOCK(fdp);
        i = --fdp->fd_refcnt;
-       FILEDESC_XUNLOCK(fdp);
-       if (i > 0)
+       if (i > 0) {
+               FILEDESC_XUNLOCK(fdp);
                return;
+       }
+
+       fdp->fd_nfiles = 0;
+
+       cdir = fdp->fd_cdir;
+       fdp->fd_cdir = NULL;
+       rdir = fdp->fd_rdir;
+       fdp->fd_rdir = NULL;
+       jdir = fdp->fd_jdir;
+       fdp->fd_jdir = NULL;
+       FILEDESC_XUNLOCK(fdp);
 
        for (i = 0; i <= fdp->fd_lastfile; i++) {
                fp = fdp->fd_ofiles[i].fde_file;
                if (fp != NULL) {
-                       FILEDESC_XLOCK(fdp);
-                       fdfree(fdp, i);
-                       FILEDESC_XUNLOCK(fdp);
+                       fdfree_last(fdp, i);
                        (void) closef(fp, td);
                }
        }
-       FILEDESC_XLOCK(fdp);
 
        if (fdp->fd_nfiles > NDFILE)
                free(fdp->fd_ofiles, M_FILEDESC);
        if (NDSLOTS(fdp->fd_nfiles) > NDSLOTS(NDFILE))
                free(fdp->fd_map, M_FILEDESC);
 
-       fdp->fd_nfiles = 0;
-
-       cdir = fdp->fd_cdir;
-       fdp->fd_cdir = NULL;
-       rdir = fdp->fd_rdir;
-       fdp->fd_rdir = NULL;
-       jdir = fdp->fd_jdir;
-       fdp->fd_jdir = NULL;
-       FILEDESC_XUNLOCK(fdp);
-
        if (cdir != NULL)
                vrele(cdir);
        if (rdir != NULL)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to