svn commit: r210475 - in head/sys: compat/freebsd32 kern vm

Alan Cox alc at FreeBSD.org
Sun Jul 25 17:43:38 UTC 2010


Author: alc
Date: Sun Jul 25 17:43:38 2010
New Revision: 210475
URL: http://svn.freebsd.org/changeset/base/210475

Log:
  Change the order in which the file name, arguments, environment, and
  shell command are stored in exec*()'s demand-paged string buffer.  For
  a "buildworld" on an 8GB amd64 multiprocessor, the new order reduces
  the number of global TLB shootdowns by 31%.  It also eliminates about
  330k page faults on the kernel address space.
  
  Change exec_shell_imgact() to use "args->begin_argv" consistently as
  the start of the argument and environment strings.  Previously, it
  would sometimes use "args->buf", which is the start of the overall
  buffer, but no longer the start of the argument and environment
  strings.  While I'm here, eliminate unnecessary passing of "&length"
  to copystr(), where we don't actually care about the length of the
  copied string.
  
  Clean up the initialization of the exec map.  In particular, use the
  correct size for an entry, and express that size in the same way that
  is used when an entry is allocated.  The old size was one page too
  large.  (This discrepancy originated in 2004 when I rewrote
  exec_map_first_page() to use sf_buf_alloc() instead of the exec map
  for mapping the first page of the executable.)
  
  Reviewed by:	kib

Modified:
  head/sys/compat/freebsd32/freebsd32_misc.c
  head/sys/kern/imgact_shell.c
  head/sys/kern/kern_exec.c
  head/sys/vm/vm_init.c

Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c	Sun Jul 25 17:40:48 2010	(r210474)
+++ head/sys/compat/freebsd32/freebsd32_misc.c	Sun Jul 25 17:43:38 2010	(r210475)
@@ -286,22 +286,23 @@ freebsd32_exec_copyin_args(struct image_
 	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
 	if (args->buf == NULL)
 		return (ENOMEM);
-	args->begin_argv = args->buf;
-	args->endp = args->begin_argv;
-	args->stringspace = ARG_MAX;
 
 	/*
 	 * Copy the file name.
 	 */
 	if (fname != NULL) {
-		args->fname = args->buf + ARG_MAX;
+		args->fname = args->buf + MAXSHELLCMDLEN;
 		error = (segflg == UIO_SYSSPACE) ?
 		    copystr(fname, args->fname, PATH_MAX, &length) :
 		    copyinstr(fname, args->fname, PATH_MAX, &length);
 		if (error != 0)
 			goto err_exit;
 	} else
-		args->fname = NULL;
+		length = 0;
+
+	args->begin_argv = args->buf + MAXSHELLCMDLEN + length;
+	args->endp = args->begin_argv;
+	args->stringspace = ARG_MAX;
 
 	/*
 	 * extract arguments first

Modified: head/sys/kern/imgact_shell.c
==============================================================================
--- head/sys/kern/imgact_shell.c	Sun Jul 25 17:40:48 2010	(r210474)
+++ head/sys/kern/imgact_shell.c	Sun Jul 25 17:43:38 2010	(r210475)
@@ -220,13 +220,13 @@ exec_shell_imgact(imgp)
 	 * the interpreter name and options-string.
 	 */
 	length = interpe - interpb;
-	bcopy(interpb, imgp->args->buf, length);
-	*(imgp->args->buf + length) = '\0';
+	bcopy(interpb, imgp->args->begin_argv, length);
+	*(imgp->args->begin_argv + length) = '\0';
 	offset = length + 1;
 	if (opte > optb) {
 		length = opte - optb;
-		bcopy(optb, imgp->args->buf + offset, length);
-		*(imgp->args->buf + offset + length) = '\0';
+		bcopy(optb, imgp->args->begin_argv + offset, length);
+		*(imgp->args->begin_argv + offset + length) = '\0';
 		offset += length + 1;
 		imgp->args->argc++;
 	}
@@ -236,12 +236,12 @@ exec_shell_imgact(imgp)
 	 * use and copy the interpreter's name to imgp->interpreter_name
 	 * for exec to use.
 	 */
-	error = copystr(fname, imgp->args->buf + offset, imgp->args->stringspace,
-	    &length);
+	error = copystr(fname, imgp->args->begin_argv + offset,
+	    imgp->args->stringspace, NULL);
 
 	if (error == 0)
 		error = copystr(imgp->args->begin_argv, imgp->interpreter_name,
-		    MAXSHELLCMDLEN, &length);
+		    MAXSHELLCMDLEN, NULL);
 
 	if (sname != NULL)
 		sbuf_delete(sname);

Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c	Sun Jul 25 17:40:48 2010	(r210474)
+++ head/sys/kern/kern_exec.c	Sun Jul 25 17:43:38 2010	(r210475)
@@ -375,7 +375,7 @@ do_execve(td, args, mac_p)
 	imgp->vmspace_destroyed = 0;
 	imgp->interpreted = 0;
 	imgp->opened = 0;
-	imgp->interpreter_name = args->buf + PATH_MAX + ARG_MAX;
+	imgp->interpreter_name = args->buf;
 	imgp->auxargs = NULL;
 	imgp->vp = NULL;
 	imgp->object = NULL;
@@ -1089,21 +1089,23 @@ exec_copyin_args(struct image_args *args
 	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
 	if (args->buf == NULL)
 		return (ENOMEM);
-	args->begin_argv = args->buf;
-	args->endp = args->begin_argv;
-	args->stringspace = ARG_MAX;
+
 	/*
 	 * Copy the file name.
 	 */
 	if (fname != NULL) {
-		args->fname = args->buf + ARG_MAX;
+		args->fname = args->buf + MAXSHELLCMDLEN;
 		error = (segflg == UIO_SYSSPACE) ?
 		    copystr(fname, args->fname, PATH_MAX, &length) :
 		    copyinstr(fname, args->fname, PATH_MAX, &length);
 		if (error != 0)
 			goto err_exit;
 	} else
-		args->fname = NULL;
+		length = 0;
+
+	args->begin_argv = args->buf + MAXSHELLCMDLEN + length;
+	args->endp = args->begin_argv;
+	args->stringspace = ARG_MAX;
 
 	/*
 	 * extract arguments first

Modified: head/sys/vm/vm_init.c
==============================================================================
--- head/sys/vm/vm_init.c	Sun Jul 25 17:40:48 2010	(r210474)
+++ head/sys/vm/vm_init.c	Sun Jul 25 17:43:38 2010	(r210475)
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 #include <sys/selinfo.h>
+#include <sys/imgact.h>
 #include <sys/pipe.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
@@ -194,7 +195,8 @@ again:
 	    (long)nswbuf * MAXPHYS, FALSE);
 	pager_map->system_map = 1;
 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
-	    exec_map_entries * (ARG_MAX + (PAGE_SIZE * 3)), FALSE);
+	    exec_map_entries * round_page(PATH_MAX + ARG_MAX + MAXSHELLCMDLEN),
+	    FALSE);
 	pipe_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, maxpipekva,
 	    FALSE);
 


More information about the svn-src-all mailing list