svn commit: r256210 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Wed Oct 9 18:41:35 UTC 2013


Author: kib
Date: Wed Oct  9 18:41:35 2013
New Revision: 256210
URL: http://svnweb.freebsd.org/changeset/base/256210

Log:
  When growing the file descriptor table, new larger memory chunk is
  allocated, but the old table is kept around to handle the case of
  threads still performing unlocked accesses to it.
  
  Grow the table exponentially instead of increasing its size by
  sizeof(long) * 8 chunks when overflowing. This mode significantly
  reduces the total memory use for the processes consuming large numbers
  of the file descriptors which open them one by one.
  
  Reported and tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Approved by:	re (marius)

Modified:
  head/sys/kern/kern_descrip.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Wed Oct  9 18:39:44 2013	(r256209)
+++ head/sys/kern/kern_descrip.c	Wed Oct  9 18:41:35 2013	(r256210)
@@ -119,6 +119,7 @@ static int	closefp(struct filedesc *fdp,
 static int	fd_first_free(struct filedesc *fdp, int low, int size);
 static int	fd_last_used(struct filedesc *fdp, int size);
 static void	fdgrowtable(struct filedesc *fdp, int nfd);
+static void	fdgrowtable_exp(struct filedesc *fdp, int nfd);
 static void	fdunused(struct filedesc *fdp, int fd);
 static void	fdused(struct filedesc *fdp, int fd);
 static int	fill_pipe_info(struct pipe *pi, struct kinfo_file *kif);
@@ -855,7 +856,7 @@ do_dup(struct thread *td, int flags, int
 				return (EMFILE);
 			}
 #endif
-			fdgrowtable(fdp, new + 1);
+			fdgrowtable_exp(fdp, new + 1);
 			oldfde = &fdp->fd_ofiles[old];
 		}
 		newfde = &fdp->fd_ofiles[new];
@@ -1478,6 +1479,24 @@ filecaps_validate(const struct filecaps 
 	    ("%s: ioctls without CAP_IOCTL", func));
 }
 
+static void
+fdgrowtable_exp(struct filedesc *fdp, int nfd)
+{
+	int nfd1, maxfd;
+
+	FILEDESC_XLOCK_ASSERT(fdp);
+
+	nfd1 = fdp->fd_nfiles * 2;
+	if (nfd1 < nfd)
+		nfd1 = nfd;
+	maxfd = getmaxfd(curproc);
+	if (maxfd < nfd1)
+		nfd1 = maxfd;
+	KASSERT(nfd <= nfd1,
+	    ("too low nfd1 %d %d %d %d", nfd, fdp->fd_nfiles, maxfd, nfd1));
+	fdgrowtable(fdp, nfd1);
+}
+
 /*
  * Grow the file table to accomodate (at least) nfd descriptors.
  */
@@ -1596,7 +1615,7 @@ fdalloc(struct thread *td, int minfd, in
 		 * fd is already equal to first free descriptor >= minfd, so
 		 * we only need to grow the table and we are done.
 		 */
-		fdgrowtable(fdp, allocfd);
+		fdgrowtable_exp(fdp, allocfd);
 	}
 
 	/*


More information about the svn-src-head mailing list