Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2012 17:12:53 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r237012 - head/sys/kern
Message-ID:  <201206131712.q5DHCrbf037618@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Wed Jun 13 17:12:53 2012
New Revision: 237012
URL: http://svn.freebsd.org/changeset/base/237012

Log:
  Re-apply reverted parts of r236935 by pjd with some changes.
  
  If fdalloc() decides to grow fdtable it does it once and at most doubles
  the size. This still may be not enough for sufficiently large fd. Use fd
  in calculations of new size in order to fix this.
  
  When growing the table, fd is already equal to first free descriptor >= minfd,
  also fdgrowtable() no longer drops the filedesc lock. As a result of this there
  is no need to retry allocation nor lookup.
  
  Fix description of fd_first_free to note all return values.
  
  In co-operation with:	pjd
  Approved by:	trasz (mentor)
  MFC after:	1 month

Modified:
  head/sys/kern/kern_descrip.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Wed Jun 13 16:40:47 2012	(r237011)
+++ head/sys/kern/kern_descrip.c	Wed Jun 13 17:12:53 2012	(r237012)
@@ -189,8 +189,9 @@ void	(*mq_fdclose)(struct thread *td, in
 static struct mtx	fdesc_mtx;
 
 /*
- * Find the first zero bit in the given bitmap, starting at low and not
- * exceeding size - 1.
+ * If low >= size, just return low. Otherwise find the first zero bit in the
+ * given bitmap, starting at low and not exceeding size - 1. Return size if
+ * not found.
  */
 static int
 fd_first_free(struct filedesc *fdp, int low, int size)
@@ -1461,7 +1462,7 @@ fdalloc(struct thread *td, int minfd, in
 {
 	struct proc *p = td->td_proc;
 	struct filedesc *fdp = p->p_fd;
-	int fd = -1, maxfd;
+	int fd = -1, maxfd, allocfd;
 #ifdef RACCT
 	int error;
 #endif
@@ -1476,25 +1477,26 @@ fdalloc(struct thread *td, int minfd, in
 	PROC_UNLOCK(p);
 
 	/*
-	 * Search the bitmap for a free descriptor.  If none is found, try
-	 * to grow the file table.  Keep at it until we either get a file
-	 * descriptor or run into process or system limits.
+	 * Search the bitmap for a free descriptor starting at minfd.
+	 * If none is found, grow the file table.
 	 */
-	for (;;) {
-		fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
-		if (fd >= maxfd)
-			return (EMFILE);
-		if (fd < fdp->fd_nfiles)
-			break;
+	fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
+	if (fd >= maxfd)
+		return (EMFILE);
+	if (fd >= fdp->fd_nfiles) {
+		allocfd = min(fd * 2, maxfd);
 #ifdef RACCT
 		PROC_LOCK(p);
-		error = racct_set(p, RACCT_NOFILE,
-		    min(fdp->fd_nfiles * 2, maxfd));
+		error = racct_set(p, RACCT_NOFILE, allocfd);
 		PROC_UNLOCK(p);
 		if (error != 0)
 			return (EMFILE);
 #endif
-		fdgrowtable(fdp, min(fdp->fd_nfiles * 2, maxfd));
+		/*
+		 * fd is already equal to first free descriptor >= minfd, so
+		 * we only need to grow the table and we are done.
+		 */
+		fdgrowtable(fdp, allocfd);
 	}
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206131712.q5DHCrbf037618>