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
This commit is contained in:
alc 2010-07-25 17:43:38 +00:00
parent 68b26f6649
commit 02c0473d35
4 changed files with 24 additions and 19 deletions

View File

@ -286,22 +286,23 @@ freebsd32_exec_copyin_args(struct image_args *args, char *fname,
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

View File

@ -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);

View File

@ -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, char *fname,
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

View File

@ -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);