summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r--sys/vm/vm_mmap.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 74b4ec2..16f331a 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/racct.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
+#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <sys/fcntl.h>
#include <sys/file.h>
@@ -87,6 +88,11 @@ __FBSDID("$FreeBSD$");
#include <sys/pmckern.h>
#endif
+int old_mlock = 0;
+SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW | CTLFLAG_TUN, &old_mlock, 0,
+ "Do not apply RLIMIT_MEMLOCK on mlockall");
+TUNABLE_INT("vm.old_mlock", &old_mlock);
+
#ifndef _SYS_SYSPROTO_H_
struct sbrk_args {
int incr;
@@ -1096,27 +1102,25 @@ sys_mlockall(td, uap)
int error;
map = &td->td_proc->p_vmspace->vm_map;
- error = 0;
+ error = priv_check(td, PRIV_VM_MLOCK);
+ if (error)
+ return (error);
if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0))
return (EINVAL);
-#if 0
/*
* If wiring all pages in the process would cause it to exceed
* a hard resource limit, return ENOMEM.
*/
- PROC_LOCK(td->td_proc);
- if (map->size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ if (!old_mlock && uap->how & MCL_CURRENT) {
+ PROC_LOCK(td->td_proc);
+ if (map->size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ PROC_UNLOCK(td->td_proc);
+ return (ENOMEM);
+ }
PROC_UNLOCK(td->td_proc);
- return (ENOMEM);
}
- PROC_UNLOCK(td->td_proc);
-#else
- error = priv_check(td, PRIV_VM_MLOCK);
- if (error)
- return (error);
-#endif
#ifdef RACCT
PROC_LOCK(td->td_proc);
error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size);
@@ -1480,6 +1484,24 @@ 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 (!old_mlock && map->flags & MAP_WIREFUTURE) {
+ if (ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) +
+ size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ racct_set_force(td->td_proc, RACCT_VMEM,
+ map->size);
+ PROC_UNLOCK(td->td_proc);
+ return (ENOMEM);
+ }
+ error = racct_set(td->td_proc, RACCT_MEMLOCK,
+ ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) +
+ size);
+ if (error != 0) {
+ racct_set_force(td->td_proc, RACCT_VMEM,
+ map->size);
+ PROC_UNLOCK(td->td_proc);
+ return (error);
+ }
+ }
PROC_UNLOCK(td->td_proc);
}
OpenPOWER on IntegriCloud