summaryrefslogtreecommitdiffstats
path: root/sys/kern
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
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')
-rw-r--r--sys/kern/kern_exit.c10
-rw-r--r--sys/kern/sys_process.c18
-rw-r--r--sys/kern/sysv_shm.c4
-rw-r--r--sys/kern/vfs_aio.c2
4 files changed, 17 insertions, 17 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;
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);
}
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 1430942..0b016f1 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -822,14 +822,14 @@ shmexit_myhook(struct vmspace *vm)
struct shmmap_state *base, *shm;
int i;
- GIANT_REQUIRED;
-
if ((base = vm->vm_shm) != NULL) {
vm->vm_shm = NULL;
+ mtx_lock(&Giant);
for (i = 0, shm = base; i < shminfo.shmseg; i++, shm++) {
if (shm->shmid != -1)
shm_delete_mapping(vm, shm);
}
+ mtx_unlock(&Giant);
free(base, M_SHM);
}
}
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index a56a54f..6d47c78 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -868,7 +868,7 @@ aio_daemon(void *uproc)
* refer to it.
*/
mycp->p_vmspace = userp->p_vmspace;
- mycp->p_vmspace->vm_refcnt++;
+ atomic_add_int(&mycp->p_vmspace->vm_refcnt, 1);
/* Activate the new mapping. */
pmap_activate(FIRST_THREAD_IN_PROC(mycp));
OpenPOWER on IntegriCloud