proc: add tree ref count
Owning the reference prevents reuse of the struct proc. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D57492
This commit is contained in:
@@ -1107,7 +1107,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
|
|||||||
|
|
||||||
KASSERT(FIRST_THREAD_IN_PROC(p),
|
KASSERT(FIRST_THREAD_IN_PROC(p),
|
||||||
("proc_reap: no residual thread!"));
|
("proc_reap: no residual thread!"));
|
||||||
uma_zfree(proc_zone, p);
|
PROC_TREE_UNREF(p);
|
||||||
atomic_add_int(&nprocs, -1);
|
atomic_add_int(&nprocs, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1051,6 +1051,7 @@ fork1(struct thread *td, struct fork_req *fr)
|
|||||||
pages = kstack_pages;
|
pages = kstack_pages;
|
||||||
/* Allocate new proc. */
|
/* Allocate new proc. */
|
||||||
newproc = uma_zalloc(proc_zone, M_WAITOK);
|
newproc = uma_zalloc(proc_zone, M_WAITOK);
|
||||||
|
PROC_TREE_REF(newproc);
|
||||||
td2 = FIRST_THREAD_IN_PROC(newproc);
|
td2 = FIRST_THREAD_IN_PROC(newproc);
|
||||||
if (td2 == NULL) {
|
if (td2 == NULL) {
|
||||||
td2 = thread_alloc(pages);
|
td2 = thread_alloc(pages);
|
||||||
@@ -1131,7 +1132,7 @@ fork1(struct thread *td, struct fork_req *fr)
|
|||||||
fail2:
|
fail2:
|
||||||
if (vm2 != NULL)
|
if (vm2 != NULL)
|
||||||
vmspace_free(vm2);
|
vmspace_free(vm2);
|
||||||
uma_zfree(proc_zone, newproc);
|
PROC_TREE_UNREF(newproc);
|
||||||
if ((flags & RFPROCDESC) != 0 && fp_procdesc != NULL) {
|
if ((flags & RFPROCDESC) != 0 && fp_procdesc != NULL) {
|
||||||
fdclose(td, fp_procdesc, *fr->fr_pd_fd);
|
fdclose(td, fp_procdesc, *fr->fr_pd_fd);
|
||||||
fdrop(fp_procdesc, td);
|
fdrop(fp_procdesc, td);
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ proc_init(void *mem, int size, int flags)
|
|||||||
p->p_pgrp = NULL;
|
p->p_pgrp = NULL;
|
||||||
TAILQ_INIT(&p->p_kqtim_stop);
|
TAILQ_INIT(&p->p_kqtim_stop);
|
||||||
STAILQ_INIT(&p->p_ktr);
|
STAILQ_INIT(&p->p_ktr);
|
||||||
|
refcount_init(&p->p_tree_refcnt, 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -779,6 +779,7 @@ struct proc {
|
|||||||
TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */
|
TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */
|
||||||
LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */
|
LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */
|
||||||
u_int p_asig; /* (c) ASYNCEXIT pending signal. */
|
u_int p_asig; /* (c) ASYNCEXIT pending signal. */
|
||||||
|
u_int p_tree_refcnt; /* (e) proctree refcount */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define p_session p_pgrp->pg_session
|
#define p_session p_pgrp->pg_session
|
||||||
@@ -804,6 +805,12 @@ struct proc {
|
|||||||
#define PROC_PROFUNLOCK(p) mtx_unlock_spin(&(p)->p_profmtx)
|
#define PROC_PROFUNLOCK(p) mtx_unlock_spin(&(p)->p_profmtx)
|
||||||
#define PROC_PROFLOCK_ASSERT(p, type) mtx_assert(&(p)->p_profmtx, (type))
|
#define PROC_PROFLOCK_ASSERT(p, type) mtx_assert(&(p)->p_profmtx, (type))
|
||||||
|
|
||||||
|
#define PROC_TREE_REF(p) refcount_acquire(&(p)->p_tree_refcnt)
|
||||||
|
#define PROC_TREE_UNREF(p) do { \
|
||||||
|
if (refcount_release(&(p)->p_tree_refcnt)) \
|
||||||
|
uma_zfree(proc_zone, p); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* These flags are kept in p_flag. */
|
/* These flags are kept in p_flag. */
|
||||||
#define P_ADVLOCK 0x00000001 /* Process may hold a POSIX advisory
|
#define P_ADVLOCK 0x00000001 /* Process may hold a POSIX advisory
|
||||||
lock. */
|
lock. */
|
||||||
|
|||||||
Reference in New Issue
Block a user