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 --- 49 unchanged lines hidden (view full) --- 58 * rights to redistribute these changes. 59 */ 60 61/* 62 * Virtual memory mapping module. 63 */ 64 65#include <sys/cdefs.h> |
66__FBSDID("$FreeBSD: head/sys/vm/vm_map.c 220373 2011-04-05 20:23:59Z trasz $"); |
67 68#include <sys/param.h> 69#include <sys/systm.h> 70#include <sys/kernel.h> 71#include <sys/ktr.h> 72#include <sys/lock.h> 73#include <sys/mutex.h> 74#include <sys/proc.h> 75#include <sys/vmmeter.h> 76#include <sys/mman.h> 77#include <sys/vnode.h> |
78#include <sys/racct.h> |
79#include <sys/resourcevar.h> 80#include <sys/file.h> 81#include <sys/sysctl.h> 82#include <sys/sysent.h> 83#include <sys/shm.h> 84 85#include <vm/vm.h> 86#include <vm/vm_param.h> --- 222 unchanged lines hidden (view full) --- 309#ifdef INVARIANTS 310 vmspace_zdtor, 311#else 312 NULL, 313#endif 314 vmspace_zinit, vmspace_zfini, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); 315} 316 |
317static void 318vmspace_container_reset(struct proc *p) 319{ 320 321 PROC_LOCK(p); 322 racct_set(p, RACCT_DATA, 0); 323 racct_set(p, RACCT_STACK, 0); 324 racct_set(p, RACCT_RSS, 0); 325 racct_set(p, RACCT_MEMLOCK, 0); 326 racct_set(p, RACCT_VMEM, 0); 327 PROC_UNLOCK(p); 328} 329 |
330static inline void 331vmspace_dofree(struct vmspace *vm) 332{ 333 334 CTR1(KTR_VM, "vmspace_free: %p", vm); 335 336 /* 337 * Make sure any SysV shm is freed, it might not have been in --- 81 unchanged lines hidden (view full) --- 419 pmap_remove_pages(vmspace_pmap(vm)); 420 /* Switch now since this proc will free vmspace */ 421 PROC_VMSPACE_LOCK(p); 422 p->p_vmspace = &vmspace0; 423 PROC_VMSPACE_UNLOCK(p); 424 pmap_activate(td); 425 vmspace_dofree(vm); 426 } |
427 vmspace_container_reset(p); |
428} 429 430/* Acquire reference to vmspace owned by another process. */ 431 432struct vmspace * 433vmspace_acquire_ref(struct proc *p) 434{ 435 struct vmspace *vm; --- 2853 unchanged lines hidden (view full) --- 3289 vm_map_entry_t new_entry, stack_entry; 3290 struct vmspace *vm = p->p_vmspace; 3291 vm_map_t map = &vm->vm_map; 3292 vm_offset_t end; 3293 size_t grow_amount, max_grow; 3294 rlim_t stacklim, vmemlim; 3295 int is_procstack, rv; 3296 struct ucred *cred; |
3297#ifdef notyet 3298 uint64_t limit; 3299#endif 3300 int error; |
3301 3302Retry: 3303 PROC_LOCK(p); 3304 stacklim = lim_cur(p, RLIMIT_STACK); 3305 vmemlim = lim_cur(p, RLIMIT_VMEM); 3306 PROC_UNLOCK(p); 3307 3308 vm_map_lock_read(map); --- 82 unchanged lines hidden (view full) --- 3391 /* 3392 * If this is the main process stack, see if we're over the stack 3393 * limit. 3394 */ 3395 if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > stacklim)) { 3396 vm_map_unlock_read(map); 3397 return (KERN_NO_SPACE); 3398 } |
3399 PROC_LOCK(p); 3400 if (is_procstack && 3401 racct_set(p, RACCT_STACK, ctob(vm->vm_ssize) + grow_amount)) { 3402 PROC_UNLOCK(p); 3403 vm_map_unlock_read(map); 3404 return (KERN_NO_SPACE); 3405 } 3406 PROC_UNLOCK(p); |
3407 3408 /* Round up the grow amount modulo SGROWSIZ */ 3409 grow_amount = roundup (grow_amount, sgrowsiz); 3410 if (grow_amount > stack_entry->avail_ssize) 3411 grow_amount = stack_entry->avail_ssize; 3412 if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > stacklim)) { 3413 grow_amount = trunc_page((vm_size_t)stacklim) - 3414 ctob(vm->vm_ssize); 3415 } |
3416#ifdef notyet 3417 PROC_LOCK(p); 3418 limit = racct_get_available(p, RACCT_STACK); 3419 PROC_UNLOCK(p); 3420 if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > limit)) 3421 grow_amount = limit - ctob(vm->vm_ssize); 3422#endif |
3423 3424 /* If we would blow our VMEM resource limit, no go */ 3425 if (map->size + grow_amount > vmemlim) { 3426 vm_map_unlock_read(map); |
3427 rv = KERN_NO_SPACE; 3428 goto out; |
3429 } |
3430 PROC_LOCK(p); 3431 if (racct_set(p, RACCT_VMEM, map->size + grow_amount)) { 3432 PROC_UNLOCK(p); 3433 vm_map_unlock_read(map); 3434 rv = KERN_NO_SPACE; 3435 goto out; 3436 } 3437 PROC_UNLOCK(p); |
3438 3439 if (vm_map_lock_upgrade(map)) 3440 goto Retry; 3441 3442 if (stack_entry == next_entry) { 3443 /* 3444 * Growing downward. 3445 */ --- 82 unchanged lines hidden (view full) --- 3528 vm_map_wire(map, 3529 (stack_entry == next_entry) ? addr : addr - grow_amount, 3530 (stack_entry == next_entry) ? stack_entry->start : addr, 3531 (p->p_flag & P_SYSTEM) 3532 ? VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES 3533 : VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 3534 } 3535 |
3536out: 3537 if (rv != KERN_SUCCESS) { 3538 PROC_LOCK(p); 3539 error = racct_set(p, RACCT_VMEM, map->size); 3540 KASSERT(error == 0, ("decreasing RACCT_VMEM failed")); 3541 error = racct_set(p, RACCT_STACK, ctob(vm->vm_ssize)); 3542 KASSERT(error == 0, ("decreasing RACCT_STACK failed")); 3543 PROC_UNLOCK(p); 3544 } 3545 |
3546 return (rv); 3547} 3548 3549/* 3550 * Unshare the specified VM space for exec. If other processes are 3551 * mapped to it, then create a new one. The new vmspace is null. 3552 */ 3553int --- 449 unchanged lines hidden --- |