diff options
author | truckman <truckman@FreeBSD.org> | 2004-02-26 00:27:04 +0000 |
---|---|---|
committer | truckman <truckman@FreeBSD.org> | 2004-02-26 00:27:04 +0000 |
commit | 1de257deb3229812024de5861eb0aaa41e471448 (patch) | |
tree | d1174aae4c9e291961c623eba11458d6d2058f11 /sys/vm/vm_mmap.c | |
parent | 50cda1680380cd332bc897ddc8f54d65ddf9aa9d (diff) | |
download | FreeBSD-src-1de257deb3229812024de5861eb0aaa41e471448.zip FreeBSD-src-1de257deb3229812024de5861eb0aaa41e471448.tar.gz |
Split the mlock() kernel code into two parts, mlock(), which unpacks
the syscall arguments and does the suser() permission check, and
kern_mlock(), which does the resource limit checking and calls
vm_map_wire(). Split munlock() in a similar way.
Enable the RLIMIT_MEMLOCK checking code in kern_mlock().
Replace calls to vslock() and vsunlock() in the sysctl code with
calls to kern_mlock() and kern_munlock() so that the sysctl code
will obey the wired memory limits.
Nuke the vslock() and vsunlock() implementations, which are no
longer used.
Add a member to struct sysctl_req to track the amount of memory
that is wired to handle the request.
Modify sysctl_wire_old_buffer() to return an error if its call to
kern_mlock() fails. Only wire the minimum of the length specified
in the sysctl request and the length specified in its argument list.
It is recommended that sysctl handlers that use sysctl_wire_old_buffer()
should specify reasonable estimates for the amount of data they
want to return so that only the minimum amount of memory is wired
no matter what length has been specified by the request.
Modify the callers of sysctl_wire_old_buffer() to look for the
error return.
Modify sysctl_old_user to obey the wired buffer length and clean up
its implementation.
Reviewed by: bms
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r-- | sys/vm/vm_mmap.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 2cad29b..6f43870 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -984,12 +984,26 @@ mlock(td, uap) struct thread *td; struct mlock_args *uap; { - vm_offset_t addr; - vm_size_t size, pageoff; int error; - addr = (vm_offset_t) uap->addr; - size = uap->len; + error = suser(td); + if (error) + return (error); + return (kern_mlock(td, (vm_offset_t)uap->addr, (vm_size_t)uap->len)); +} + +/* + * MPSAFE + */ +int +kern_mlock(td, addr, size) + struct thread *td; + vm_offset_t addr; + vm_size_t size; +{ + vm_size_t pageoff; + struct proc *proc = td->td_proc; + int error; pageoff = (addr & PAGE_MASK); addr -= pageoff; @@ -1003,21 +1017,15 @@ mlock(td, uap) if (atop(size) + cnt.v_wire_count > vm_page_max_wired) return (EAGAIN); -#if 0 - PROC_LOCK(td->td_proc); - if (size + ptoa(pmap_wired_count(vm_map_pmap(&td->td_proc->p_vmspace->vm_map))) > - lim_cur(td->td_proc, RLIMIT_MEMLOCK)) { - PROC_UNLOCK(td->td_proc); + PROC_LOCK(proc); + if (size + ptoa(pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) > + lim_cur(proc, RLIMIT_MEMLOCK)) { + PROC_UNLOCK(proc); return (ENOMEM); } - PROC_UNLOCK(td->td_proc); -#else - error = suser(td); - if (error) - return (error); -#endif + PROC_UNLOCK(proc); - error = vm_map_wire(&td->td_proc->p_vmspace->vm_map, addr, + error = vm_map_wire(&proc->p_vmspace->vm_map, addr, addr + size, VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1133,12 +1141,25 @@ munlock(td, uap) struct thread *td; struct munlock_args *uap; { - vm_offset_t addr; - vm_size_t size, pageoff; int error; - addr = (vm_offset_t) uap->addr; - size = uap->len; + error = suser(td); + if (error) + return (error); + return (kern_munlock(td, (vm_offset_t)uap->addr, (vm_size_t)uap->len)); +} + +/* + * MPSAFE + */ +int +kern_munlock(td, addr, size) + struct thread *td; + vm_offset_t addr; + vm_size_t size; +{ + vm_size_t pageoff; + int error; pageoff = (addr & PAGE_MASK); addr -= pageoff; @@ -1149,10 +1170,6 @@ munlock(td, uap) if (addr + size < addr) return (EINVAL); - error = suser(td); - if (error) - return (error); - error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, addr, addr + size, VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); return (error == KERN_SUCCESS ? 0 : ENOMEM); |