diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2020-09-08 23:48:19 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2020-09-08 23:48:19 +0000 |
commit | 67a659d2827b340badda0040e4ccfefe2962f003 (patch) | |
tree | 8054c5a1b8f74debe6090353c492696afce9c535 /sys/vm | |
parent | fbf2a778760f24565eab950ced3e2ad1df4cf844 (diff) | |
download | src-67a659d2827b340badda0040e4ccfefe2962f003.tar.gz src-67a659d2827b340badda0040e4ccfefe2962f003.zip |
Add kern_mmap_racct_check(), a helper to verify limits in vm_mmap*().
Reviewed by: markj
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D24652
Notes
Notes:
svn path=/head/; revision=365486
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_mmap.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 03f236aac132..e0f3da8ed704 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1509,6 +1509,39 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, return (error); } +int +kern_mmap_racct_check(struct thread *td, vm_map_t map, vm_size_t size) +{ + int error; + + RACCT_PROC_LOCK(td->td_proc); + if (map->size + size > lim_cur(td, RLIMIT_VMEM)) { + RACCT_PROC_UNLOCK(td->td_proc); + return (ENOMEM); + } + if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) { + RACCT_PROC_UNLOCK(td->td_proc); + return (ENOMEM); + } + if (!old_mlock && map->flags & MAP_WIREFUTURE) { + if (ptoa(pmap_wired_count(map->pmap)) + size > + lim_cur(td, RLIMIT_MEMLOCK)) { + racct_set_force(td->td_proc, RACCT_VMEM, map->size); + RACCT_PROC_UNLOCK(td->td_proc); + return (ENOMEM); + } + error = racct_set(td->td_proc, RACCT_MEMLOCK, + ptoa(pmap_wired_count(map->pmap)) + size); + if (error != 0) { + racct_set_force(td->td_proc, RACCT_VMEM, map->size); + RACCT_PROC_UNLOCK(td->td_proc); + return (error); + } + } + RACCT_PROC_UNLOCK(td->td_proc); + return (0); +} + /* * Internal version of mmap that maps a specific VM object into an * map. Called by mmap for MAP_ANON, vm_mmap, shm_mmap, and vn_mmap. @@ -1518,39 +1551,15 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff, boolean_t writecounted, struct thread *td) { - boolean_t curmap, fitit; vm_offset_t max_addr; int docow, error, findspace, rv; + bool curmap, fitit; curmap = map == &td->td_proc->p_vmspace->vm_map; if (curmap) { - RACCT_PROC_LOCK(td->td_proc); - if (map->size + size > lim_cur(td, RLIMIT_VMEM)) { - RACCT_PROC_UNLOCK(td->td_proc); - return (ENOMEM); - } - if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) { - RACCT_PROC_UNLOCK(td->td_proc); - return (ENOMEM); - } - if (!old_mlock && map->flags & MAP_WIREFUTURE) { - if (ptoa(pmap_wired_count(map->pmap)) + size > - lim_cur(td, RLIMIT_MEMLOCK)) { - racct_set_force(td->td_proc, RACCT_VMEM, - map->size); - RACCT_PROC_UNLOCK(td->td_proc); - return (ENOMEM); - } - error = racct_set(td->td_proc, RACCT_MEMLOCK, - ptoa(pmap_wired_count(map->pmap)) + size); - if (error != 0) { - racct_set_force(td->td_proc, RACCT_VMEM, - map->size); - RACCT_PROC_UNLOCK(td->td_proc); - return (error); - } - } - RACCT_PROC_UNLOCK(td->td_proc); + error = kern_mmap_racct_check(td, map, size); + if (error != 0) + return (error); } /* |