summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-07-27 03:53:41 +0000
committeralc <alc@FreeBSD.org>2004-07-27 03:53:41 +0000
commit8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824 (patch)
tree6d7127f6cedfdcd82a7c1768b6c913502023d8cf /sys/kern/kern_exit.c
parenta745685147cf8bdd139918b29529822fc40acdf6 (diff)
downloadFreeBSD-src-8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824.zip
FreeBSD-src-8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824.tar.gz
- Use atomic ops for updating the vmspace's refcnt and exitingcnt.
- Push down Giant into shmexit(). (Giant is acquired only if the vmspace contains shm segments.) - Eliminate the acquisition of Giant from proc_rwmem(). - Reduce the scope of Giant in exit1(), uncovering the destruction of the address space.
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index a268771..78f3feb 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -114,6 +114,7 @@ exit1(struct thread *td, int rv)
struct ucred *tracecred;
#endif
struct plimit *plim;
+ int refcnt;
/*
* Drop Giant if caller has it. Eventually we should warn about
@@ -254,7 +255,6 @@ retry:
}
mtx_unlock(&ppeers_lock);
- mtx_lock(&Giant);
/* The next two chunks should probably be moved to vmspace_exit. */
vm = p->p_vmspace;
/*
@@ -272,8 +272,11 @@ retry:
* by vmspace_exit() (which decrements exitingcnt) cleans up the
* remainder.
*/
- ++vm->vm_exitingcnt;
- if (--vm->vm_refcnt == 0) {
+ atomic_add_int(&vm->vm_exitingcnt, 1);
+ do
+ refcnt = vm->vm_refcnt;
+ while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1));
+ if (refcnt == 1) {
shmexit(vm);
pmap_remove_pages(vmspace_pmap(vm), vm_map_min(&vm->vm_map),
vm_map_max(&vm->vm_map));
@@ -281,6 +284,7 @@ retry:
vm_map_max(&vm->vm_map));
}
+ mtx_lock(&Giant);
sx_xlock(&proctree_lock);
if (SESS_LEADER(p)) {
struct session *sp;
OpenPOWER on IntegriCloud