diff options
author | alc <alc@FreeBSD.org> | 2004-07-27 03:53:41 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-07-27 03:53:41 +0000 |
commit | 8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824 (patch) | |
tree | 6d7127f6cedfdcd82a7c1768b6c913502023d8cf /sys/kern/sys_process.c | |
parent | a745685147cf8bdd139918b29529822fc40acdf6 (diff) | |
download | FreeBSD-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/sys_process.c')
-rw-r--r-- | sys/kern/sys_process.c | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 11bbe3e..9dad83a 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -153,24 +153,21 @@ proc_rwmem(struct proc *p, struct uio *uio) vm_object_t backing_object, object = NULL; vm_offset_t pageno = 0; /* page number */ vm_prot_t reqprot; - int error, writing; + int error, refcnt, writing; - mtx_lock(&Giant); /* * if the vmspace is in the midst of being deallocated or the * process is exiting, don't try to grab anything. The page table * usage in that process can be messed up. */ vm = p->p_vmspace; - if ((p->p_flag & P_WEXIT)) { - mtx_unlock(&Giant); + if ((p->p_flag & P_WEXIT)) return (EFAULT); - } - if (vm->vm_refcnt < 1) { - mtx_unlock(&Giant); - return (EFAULT); - } - ++vm->vm_refcnt; + do { + if ((refcnt = vm->vm_refcnt) < 1) + return (EFAULT); + } while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt + 1)); + /* * The map we want... */ @@ -278,7 +275,6 @@ proc_rwmem(struct proc *p, struct uio *uio) } while (error == 0 && uio->uio_resid > 0); vmspace_free(vm); - mtx_unlock(&Giant); return (error); } |