1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * The Mach Operating System project at Carnegie-Mellon University. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 43 unchanged lines hidden (view full) --- 52 * Carnegie Mellon University 53 * Pittsburgh PA 15213-3890 54 * 55 * any improvements or extensions that they make and grant Carnegie the 56 * rights to redistribute these changes. 57 */ 58 59#include <sys/cdefs.h> |
60__FBSDID("$FreeBSD: head/sys/vm/vm_glue.c 220373 2011-04-05 20:23:59Z trasz $"); |
61 62#include "opt_vm.h" 63#include "opt_kstack_pages.h" 64#include "opt_kstack_max_pages.h" 65 66#include <sys/param.h> 67#include <sys/systm.h> 68#include <sys/limits.h> 69#include <sys/lock.h> 70#include <sys/mutex.h> 71#include <sys/proc.h> |
72#include <sys/racct.h> |
73#include <sys/resourcevar.h> 74#include <sys/sched.h> 75#include <sys/sf_buf.h> 76#include <sys/shm.h> 77#include <sys/vmmeter.h> 78#include <sys/sx.h> 79#include <sys/sysctl.h> 80 --- 97 unchanged lines hidden (view full) --- 178 vm_map_unlock_read(map); 179 return (rv == TRUE); 180} 181 182int 183vslock(void *addr, size_t len) 184{ 185 vm_offset_t end, last, start; |
186 unsigned long nsize; |
187 vm_size_t npages; 188 int error; 189 190 last = (vm_offset_t)addr + len; 191 start = trunc_page((vm_offset_t)addr); 192 end = round_page(last); 193 if (last < (vm_offset_t)addr || end < (vm_offset_t)addr) 194 return (EINVAL); 195 npages = atop(end - start); 196 if (npages > vm_page_max_wired) 197 return (ENOMEM); 198 PROC_LOCK(curproc); |
199 nsize = ptoa(npages + 200 pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map))); 201 if (nsize > lim_cur(curproc, RLIMIT_MEMLOCK)) { |
202 PROC_UNLOCK(curproc); 203 return (ENOMEM); 204 } |
205 if (racct_set(curproc, RACCT_MEMLOCK, nsize)) { 206 PROC_UNLOCK(curproc); 207 return (ENOMEM); 208 } |
209 PROC_UNLOCK(curproc); 210#if 0 211 /* 212 * XXX - not yet 213 * 214 * The limit for transient usage of wired pages should be 215 * larger than for "permanent" wired pages (mlock()). 216 * 217 * Also, the sysctl code, which is the only present user 218 * of vslock(), does a hard loop on EAGAIN. 219 */ 220 if (npages + cnt.v_wire_count > vm_page_max_wired) 221 return (EAGAIN); 222#endif 223 error = vm_map_wire(&curproc->p_vmspace->vm_map, start, end, 224 VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); |
225 if (error != KERN_SUCCESS) { 226 PROC_LOCK(curproc); 227 racct_set(curproc, RACCT_MEMLOCK, 228 ptoa(pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map)))); 229 PROC_UNLOCK(curproc); 230 } |
231 /* 232 * Return EFAULT on error to match copy{in,out}() behaviour 233 * rather than returning ENOMEM like mlock() would. 234 */ 235 return (error == KERN_SUCCESS ? 0 : EFAULT); 236} 237 238void 239vsunlock(void *addr, size_t len) 240{ 241 242 /* Rely on the parameter sanity checks performed by vslock(). */ 243 (void)vm_map_unwire(&curproc->p_vmspace->vm_map, 244 trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len), 245 VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); |
246 247 PROC_LOCK(curproc); 248 racct_set(curproc, RACCT_MEMLOCK, 249 ptoa(pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map)))); 250 PROC_UNLOCK(curproc); |
251} 252 253/* 254 * Pin the page contained within the given object at the given offset. If the 255 * page is not resident, allocate and load it using the given object's pager. 256 * Return the pinned page if successful; otherwise, return NULL. 257 */ 258static vm_page_t --- 825 unchanged lines hidden --- |