summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_mmap.c
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2011-04-05 20:23:59 +0000
committertrasz <trasz@FreeBSD.org>2011-04-05 20:23:59 +0000
commit92bec9b84c91c81031aecc423fd62e9a9b27b631 (patch)
treeff083b539865dc2215b27827e89a3109487e5979 /sys/vm/vm_mmap.c
parentfffd1b22a504ec96e5bf538ba769d4ea4f5c8ded (diff)
downloadFreeBSD-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.c45
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);
/*
OpenPOWER on IntegriCloud