diff options
author | phk <phk@FreeBSD.org> | 1999-11-16 20:31:58 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1999-11-16 20:31:58 +0000 |
commit | cc6b664e2eb821b39837e7bb980e5ee87e201491 (patch) | |
tree | 65eeb4add32e588f36f28e2a0bb819c17a67ff70 /sys/kern/kern_exec.c | |
parent | 47e5f46c7642e6d8e2ed20c8afca59596d3c2dc1 (diff) | |
download | FreeBSD-src-cc6b664e2eb821b39837e7bb980e5ee87e201491.zip FreeBSD-src-cc6b664e2eb821b39837e7bb980e5ee87e201491.tar.gz |
Introduce commandline caching in the kernel.
This fixes some nasty procfs problems for SMP, makes ps(1) run much faster,
and makes ps(1) even less dependent on /proc which will aid chroot and
jails alike.
To disable this facility and revert to previous behaviour:
sysctl -w kern.ps_arg_cache_limit=0
For full details see the current@FreeBSD.org mail-archives.
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 35aa228..900da01 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -63,6 +63,8 @@ #include <machine/reg.h> +MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); + static long *exec_copyout_strings __P((struct image_params *)); static long ps_strings = PS_STRINGS; @@ -71,6 +73,10 @@ SYSCTL_LONG(_kern, KERN_PS_STRINGS, ps_strings, CTLFLAG_RD, &ps_strings, ""); static long usrstack = USRSTACK; SYSCTL_LONG(_kern, KERN_USRSTACK, usrstack, CTLFLAG_RD, &usrstack, ""); +u_long ps_arg_cache_limit = PAGE_SIZE / 16; +SYSCTL_LONG(_kern, OID_AUTO, ps_arg_cache_limit, CTLFLAG_RW, + &ps_arg_cache_limit, ""); + /* * Each of the items is a pointer to a `const struct execsw', hence the * double pointer here. @@ -316,6 +322,21 @@ interpret: setregs(p, imgp->entry_addr, (u_long)(uintptr_t)stack_base, imgp->ps_strings); + /* Free any previous argument cache */ + if (p->p_args && --p->p_args->ar_ref == 0) + FREE(p->p_args, M_PARGS); + p->p_args = NULL; + + /* Cache arguments if they fit inside our allowance */ + i = imgp->endargs - imgp->stringbase; + if (ps_arg_cache_limit >= i + sizeof(struct pargs)) { + MALLOC(p->p_args, struct pargs *, sizeof(struct pargs) + i, + M_PARGS, M_WAITOK); + p->p_args->ar_ref = 1; + p->p_args->ar_length = i; + bcopy(imgp->stringbase, p->p_args->ar_args, i); + } + exec_fail_dealloc: /* @@ -511,6 +532,8 @@ exec_extract_strings(imgp) } } + imgp->endargs = imgp->stringp; + /* * extract environment strings */ |