#include <sys/user.h>
#include <sys/reg.h>
+#include <sys/refcount.h>
#include <sys/thread2.h>
#include <sys/mplock2.h>
struct lwp *lp = td->td_lwp;
struct proc *p = td->td_proc;
register_t *stack_base;
+ struct pargs *pa;
int error, len, i;
struct image_params image_params, *imgp;
struct vattr attr;
}
KKASSERT(p);
+ lwkt_gettoken(&p->p_token);
imgp = &image_params;
/*
/* Set the access time on the vnode */
vn_mark_atime(imgp->vp, td);
- /* Free any previous argument cache */
- if (p->p_args && --p->p_args->ar_ref == 0)
- FREE(p->p_args, M_PARGS);
+ /*
+ * Free any previous argument cache
+ */
+ pa = p->p_args;
p->p_args = NULL;
+ if (pa && refcount_release(&pa->ar_ref)) {
+ kfree(pa, M_PARGS);
+ pa = NULL;
+ }
- /* Cache arguments if they fit inside our allowance */
+ /*
+ * Cache arguments if they fit inside our allowance
+ */
i = imgp->args->begin_envv - imgp->args->begin_argv;
- 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->args->begin_argv, p->p_args->ar_args, i);
+ if (sizeof(struct pargs) + i <= ps_arg_cache_limit) {
+ pa = kmalloc(sizeof(struct pargs) + i, M_PARGS, M_WAITOK);
+ refcount_init(&pa->ar_ref, 1);
+ pa->ar_length = i;
+ bcopy(imgp->args->begin_argv, pa->ar_args, i);
+ KKASSERT(p->p_args == NULL);
+ p->p_args = pa;
}
exec_fail_dealloc:
if (error == 0) {
++mycpu->gd_cnt.v_exec;
+ lwkt_reltoken(&p->p_token);
return (0);
}
*/
if (imgp->vmspace_destroyed & 2)
p->p_flag &= ~P_INEXEC;
+ lwkt_reltoken(&p->p_token);
if (imgp->vmspace_destroyed) {
/*
* Sorry, no more process anymore. exit gracefully.
p->p_flag |= P_INEXEC;
/*
- * Prevent a pending AIO from modifying the new address space.
- */
- aio_proc_rundown(imgp->proc);
-
- /*
* Blow away entire process VM, if address space not shared,
* otherwise, create a new VM space so that other threads are
* not disrupted. If we are execing a resident vmspace we