diff options
author | alfred <alfred@FreeBSD.org> | 2001-05-19 01:28:09 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2001-05-19 01:28:09 +0000 |
commit | a3f0842419d98da211706f921fc626e160cd960b (patch) | |
tree | e86922a5639c32e1242d4f3088fc487f3be5b236 /sys/vm/vm_glue.c | |
parent | 9eda9187f024233436e6a743f13bd938b1a0f19c (diff) | |
download | FreeBSD-src-a3f0842419d98da211706f921fc626e160cd960b.zip FreeBSD-src-a3f0842419d98da211706f921fc626e160cd960b.tar.gz |
Introduce a global lock for the vm subsystem (vm_mtx).
vm_mtx does not recurse and is required for most low level
vm operations.
faults can not be taken without holding Giant.
Memory subsystems can now call the base page allocators safely.
Almost all atomic ops were removed as they are covered under the
vm mutex.
Alpha and ia64 now need to catch up to i386's trap handlers.
FFS and NFS have been tested, other filesystems will need minor
changes (grabbing the vm lock when twiddling page properties).
Reviewed (partially) by: jake, jhb
Diffstat (limited to 'sys/vm/vm_glue.c')
-rw-r--r-- | sys/vm/vm_glue.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index a180ae3..37c580a 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -161,6 +161,7 @@ useracc(addr, len, rw) || (vm_offset_t) addr + len < (vm_offset_t) addr) { return (FALSE); } + mtx_lock(&vm_mtx); map = &curproc->p_vmspace->vm_map; vm_map_lock_read(map); /* @@ -172,6 +173,7 @@ useracc(addr, len, rw) trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len), prot); map->hint = save_hint; vm_map_unlock_read(map); + mtx_unlock(&vm_mtx); return (rv == TRUE); } @@ -181,8 +183,12 @@ vslock(addr, len) caddr_t addr; u_int len; { - vm_map_pageable(&curproc->p_vmspace->vm_map, trunc_page((vm_offset_t)addr), + + mtx_lock(&vm_mtx); + vm_map_pageable(&curproc->p_vmspace->vm_map, + trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len), FALSE); + mtx_unlock(&vm_mtx); } void @@ -190,8 +196,12 @@ vsunlock(addr, len) caddr_t addr; u_int len; { - vm_map_pageable(&curproc->p_vmspace->vm_map, trunc_page((vm_offset_t)addr), + + mtx_lock(&vm_mtx); + vm_map_pageable(&curproc->p_vmspace->vm_map, + trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len), TRUE); + mtx_unlock(&vm_mtx); } /* @@ -201,6 +211,8 @@ vsunlock(addr, len) * machine-dependent layer to fill those in and make the new process * ready to run. The new process is set up so that it returns directly * to user mode to avoid stack copying and relocation problems. + * + * Called without vm_mtx. */ void vm_fork(p1, p2, flags) @@ -209,6 +221,7 @@ vm_fork(p1, p2, flags) { register struct user *up; + mtx_lock(&vm_mtx); if ((flags & RFPROC) == 0) { /* * Divorce the memory, if it is shared, essentially @@ -221,6 +234,7 @@ vm_fork(p1, p2, flags) } } cpu_fork(p1, p2, flags); + mtx_unlock(&vm_mtx); return; } @@ -275,6 +289,7 @@ vm_fork(p1, p2, flags) * and make the child ready to run. */ cpu_fork(p1, p2, flags); + mtx_unlock(&vm_mtx); } /* @@ -360,10 +375,13 @@ scheduler(dummy) mtx_assert(&Giant, MA_OWNED | MA_NOTRECURSED); loop: + mtx_lock(&vm_mtx); if (vm_page_count_min()) { VM_WAIT; + mtx_unlock(&vm_mtx); goto loop; } + mtx_unlock(&vm_mtx); mtx_unlock(&Giant); pp = NULL; @@ -442,6 +460,9 @@ SYSCTL_INT(_vm, OID_AUTO, swap_idle_threshold2, * If any procs have been sleeping/stopped for at least maxslp seconds, * they are swapped. Else, we swap the longest-sleeping or stopped process, * if any, otherwise the longest-resident process. + * + * Can block + * must be called with vm_mtx */ void swapout_procs(action) @@ -452,6 +473,8 @@ int action; int outpri, outpri2; int didswap = 0; + mtx_assert(&vm_mtx, MA_OWNED); + mtx_unlock(&vm_mtx); outp = outp2 = NULL; outpri = outpri2 = INT_MIN; sx_slock(&allproc_lock); @@ -465,6 +488,11 @@ retry: PROC_UNLOCK(p); continue; } + /* + * only aiod changes vmspace, however it will be + * skipped because of the if statement above checking + * for P_SYSTEM + */ vm = p->p_vmspace; mtx_lock_spin(&sched_lock); if ((p->p_sflag & (PS_INMEM|PS_SWAPPING)) != PS_INMEM) { @@ -516,6 +544,7 @@ retry: } mtx_unlock_spin(&sched_lock); + mtx_lock(&vm_mtx); #if 0 /* * XXX: This is broken. We release the lock we @@ -531,7 +560,7 @@ retry: */ if (lockmgr(&vm->vm_map.lock, LK_EXCLUSIVE | LK_NOWAIT, - (void *)0, curproc)) { + NULL, curproc)) { vmspace_free(vm); PROC_UNLOCK(p); continue; @@ -548,8 +577,10 @@ retry: swapout(p); vmspace_free(vm); didswap++; + mtx_unlock(&vm_mtx); goto retry; } + mtx_unlock(&vm_mtx); PROC_UNLOCK(p); } } @@ -558,6 +589,7 @@ retry: * If we swapped something out, and another process needed memory, * then wakeup the sched process. */ + mtx_lock(&vm_mtx); if (didswap) wakeup(&proc0); } |