diff options
author | trasz <trasz@FreeBSD.org> | 2011-04-05 20:23:59 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2011-04-05 20:23:59 +0000 |
commit | 92bec9b84c91c81031aecc423fd62e9a9b27b631 (patch) | |
tree | ff083b539865dc2215b27827e89a3109487e5979 /sys/vm/vm_mmap.c | |
parent | fffd1b22a504ec96e5bf538ba769d4ea4f5c8ded (diff) | |
download | FreeBSD-src-92bec9b84c91c81031aecc423fd62e9a9b27b631.zip FreeBSD-src-92bec9b84c91c81031aecc423fd62e9a9b27b631.tar.gz |
Add accounting for most of the memory-related resources.
Sponsored by: The FreeBSD Foundation
Reviewed by: kib (earlier version)
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r-- | sys/vm/vm_mmap.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index f2b317e..37949a5 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include <sys/filedesc.h> #include <sys/priv.h> #include <sys/proc.h> +#include <sys/racct.h> #include <sys/resource.h> #include <sys/resourcevar.h> #include <sys/vnode.h> @@ -991,6 +992,7 @@ mlock(td, uap) struct proc *proc; vm_offset_t addr, end, last, start; vm_size_t npages, size; + unsigned long nsize; int error; error = priv_check(td, PRIV_VM_MLOCK); @@ -1008,17 +1010,28 @@ mlock(td, uap) return (ENOMEM); proc = td->td_proc; PROC_LOCK(proc); - if (ptoa(npages + - pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) > - lim_cur(proc, RLIMIT_MEMLOCK)) { + nsize = ptoa(npages + + pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))); + if (nsize > lim_cur(proc, RLIMIT_MEMLOCK)) { PROC_UNLOCK(proc); return (ENOMEM); } PROC_UNLOCK(proc); if (npages + cnt.v_wire_count > vm_page_max_wired) return (EAGAIN); + PROC_LOCK(proc); + error = racct_set(proc, RACCT_MEMLOCK, nsize); + PROC_UNLOCK(proc); + if (error != 0) + return (ENOMEM); error = vm_map_wire(&proc->p_vmspace->vm_map, start, end, VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); + if (error != KERN_SUCCESS) { + PROC_LOCK(proc); + racct_set(proc, RACCT_MEMLOCK, + ptoa(pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map)))); + PROC_UNLOCK(proc); + } return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1061,6 +1074,11 @@ mlockall(td, uap) if (error) return (error); #endif + PROC_LOCK(td->td_proc); + error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size); + PROC_UNLOCK(td->td_proc); + if (error != 0) + return (ENOMEM); if (uap->how & MCL_FUTURE) { vm_map_lock(map); @@ -1080,6 +1098,12 @@ mlockall(td, uap) VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); error = (error == KERN_SUCCESS ? 0 : EAGAIN); } + if (error != KERN_SUCCESS) { + PROC_LOCK(td->td_proc); + racct_set(td->td_proc, RACCT_MEMLOCK, + ptoa(pmap_wired_count(vm_map_pmap(&td->td_proc->p_vmspace->vm_map)))); + PROC_UNLOCK(td->td_proc); + } return (error); } @@ -1114,6 +1138,11 @@ munlockall(td, uap) /* Forcibly unwire all pages. */ error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map), VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); + if (error == KERN_SUCCESS) { + PROC_LOCK(td->td_proc); + racct_set(td->td_proc, RACCT_MEMLOCK, 0); + PROC_UNLOCK(td->td_proc); + } return (error); } @@ -1148,6 +1177,11 @@ munlock(td, uap) return (EINVAL); error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end, VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); + if (error == KERN_SUCCESS) { + PROC_LOCK(td->td_proc); + racct_sub(td->td_proc, RACCT_MEMLOCK, ptoa(end - start)); + PROC_UNLOCK(td->td_proc); + } return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1380,6 +1414,11 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, PROC_UNLOCK(td->td_proc); return(ENOMEM); } + if (racct_set(td->td_proc, RACCT_VMEM, + td->td_proc->p_vmspace->vm_map.size + size)) { + PROC_UNLOCK(td->td_proc); + return (ENOMEM); + } PROC_UNLOCK(td->td_proc); /* |