summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_meter.c
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2006-05-29 21:28:56 +0000
committertegge <tegge@FreeBSD.org>2006-05-29 21:28:56 +0000
commit0d5f19116220da1e7a0df73c804bebeb5efdf862 (patch)
tree2227714d6a33f215f9677debe94c947b9e3fc437 /sys/vm/vm_meter.c
parentff05f5f32b9783ffa4f05a2b79b7e54056d2f947 (diff)
downloadFreeBSD-src-0d5f19116220da1e7a0df73c804bebeb5efdf862.zip
FreeBSD-src-0d5f19116220da1e7a0df73c804bebeb5efdf862.tar.gz
Close race between vmspace_exitfree() and exit1() and races between
vmspace_exitfree() and vmspace_free() which could result in the same vmspace being freed twice. Factor out part of exit1() into new function vmspace_exit(). Attach to vmspace0 to allow old vmspace to be freed earlier. Add new function, vmspace_acquire_ref(), for obtaining a vmspace reference for a vmspace belonging to another process. Avoid changing vmspace refcount from 0 to 1 since that could also lead to the same vmspace being freed twice. Change vmtotal() and swapout_procs() to use vmspace_acquire_ref(). Reviewed by: alc
Diffstat (limited to 'sys/vm/vm_meter.c')
-rw-r--r--sys/vm/vm_meter.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index c5d3abc..1665fda 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -115,6 +115,7 @@ vmtotal(SYSCTL_HANDLER_ARGS)
vm_map_t map;
int paging;
struct thread *td;
+ struct vmspace *vm;
totalp = &total;
bzero(totalp, sizeof *totalp);
@@ -185,7 +186,10 @@ vmtotal(SYSCTL_HANDLER_ARGS)
* Note active objects.
*/
paging = 0;
- map = &p->p_vmspace->vm_map;
+ vm = vmspace_acquire_ref(p);
+ if (vm == NULL)
+ continue;
+ map = &vm->vm_map;
vm_map_lock_read(map);
for (entry = map->header.next;
entry != &map->header; entry = entry->next) {
@@ -198,6 +202,7 @@ vmtotal(SYSCTL_HANDLER_ARGS)
VM_OBJECT_UNLOCK(object);
}
vm_map_unlock_read(map);
+ vmspace_free(vm);
if (paging)
totalp->t_pw++;
}
OpenPOWER on IntegriCloud