Author: mjg
Date: Fri Oct 31 09:19:46 2014
New Revision: 273894
URL: https://svnweb.freebsd.org/changeset/base/273894

Log:
  filedesc: iterate over fd table only once in fdcopy
  
  While here add 'fdused_init' which does not perform unnecessary work.
  
  Drop FILEDESC_LOCK_ASSERT from fdisused and rely on callers to hold
  it when appropriate. This function is only used with INVARIANTS.
  
  No functional changes intended.

Modified:
  head/sys/kern/kern_descrip.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c        Fri Oct 31 09:15:59 2014        
(r273893)
+++ head/sys/kern/kern_descrip.c        Fri Oct 31 09:19:46 2014        
(r273894)
@@ -238,8 +238,6 @@ static int
 fdisused(struct filedesc *fdp, int fd)
 {
 
-       FILEDESC_LOCK_ASSERT(fdp);
-
        KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
            ("file descriptor %d out of range (0, %d)", fd, fdp->fd_nfiles));
 
@@ -251,14 +249,21 @@ fdisused(struct filedesc *fdp, int fd)
  * Mark a file descriptor as used.
  */
 static void
-fdused(struct filedesc *fdp, int fd)
+fdused_init(struct filedesc *fdp, int fd)
 {
 
-       FILEDESC_XLOCK_ASSERT(fdp);
-
        KASSERT(!fdisused(fdp, fd), ("fd=%d is already used", fd));
 
        fdp->fd_map[NDSLOT(fd)] |= NDBIT(fd);
+}
+
+static void
+fdused(struct filedesc *fdp, int fd)
+{
+
+       FILEDESC_XLOCK_ASSERT(fdp);
+
+       fdused_init(fdp, fd);
        if (fd > fdp->fd_lastfile)
                fdp->fd_lastfile = fd;
        if (fd == fdp->fd_freefile)
@@ -1912,28 +1917,23 @@ fdcopy(struct filedesc *fdp)
        newfdp->fd_freefile = -1;
        for (i = 0; i <= fdp->fd_lastfile; ++i) {
                ofde = &fdp->fd_ofiles[i];
-               if (ofde->fde_file != NULL &&
-                   ofde->fde_file->f_ops->fo_flags & DFLAG_PASSABLE) {
-                       nfde = &newfdp->fd_ofiles[i];
-                       *nfde = *ofde;
-                       filecaps_copy(&ofde->fde_caps, &nfde->fde_caps);
-                       fhold(nfde->fde_file);
-                       newfdp->fd_lastfile = i;
-               } else {
+               if (ofde->fde_file == NULL ||
+                   (ofde->fde_file->f_ops->fo_flags & DFLAG_PASSABLE) == 0) {
                        if (newfdp->fd_freefile == -1)
                                newfdp->fd_freefile = i;
+                       continue;
                }
-       }
-       newfdp->fd_cmask = fdp->fd_cmask;
-       FILEDESC_SUNLOCK(fdp);
-       FILEDESC_XLOCK(newfdp);
-       for (i = 0; i <= newfdp->fd_lastfile; ++i) {
-               if (newfdp->fd_ofiles[i].fde_file != NULL)
-                       fdused(newfdp, i);
+               nfde = &newfdp->fd_ofiles[i];
+               *nfde = *ofde;
+               filecaps_copy(&ofde->fde_caps, &nfde->fde_caps);
+               fhold(nfde->fde_file);
+               fdused_init(newfdp, i);
+               newfdp->fd_lastfile = i;
        }
        if (newfdp->fd_freefile == -1)
                newfdp->fd_freefile = i;
-       FILEDESC_XUNLOCK(newfdp);
+       newfdp->fd_cmask = fdp->fd_cmask;
+       FILEDESC_SUNLOCK(fdp);
        return (newfdp);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to