Date: Thu, 30 Aug 2012 13:06:44 +0400 From: Andrey Zonov <zont@FreeBSD.org> To: freebsd-arch@freebsd.org Subject: Re: [patch] unprivileged mlock(2) Message-ID: <503F2D24.8050103@FreeBSD.org> In-Reply-To: <20120829092318.GW33100@deviant.kiev.zoral.com.ua> References: <503DD433.2030108@FreeBSD.org> <201208290906.q7T96C9j032802@gw.catspoiler.org> <20120829092318.GW33100@deviant.kiev.zoral.com.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig5C2551C41E5B3832AFE69806 Content-Type: multipart/mixed; boundary="------------020105090900020700090502" This is a multi-part message in MIME format. --------------020105090900020700090502 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hi, So, I've got the first version of the patch (attached) which fixes memory locked limit checking and accounting. I also want to change 'pmap_wired_count(vm_map_pmap(map))' with 'vmspace_wired_count(vmspace)', and apply the patch below separately: Index: sys/vm/vm_mmap.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/vm/vm_mmap.c (revision 239611) +++ sys/vm/vm_mmap.c (working copy) @@ -1483,11 +1483,13 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_= t PROC_UNLOCK(td->td_proc); return (ENOMEM); } +#ifdef RACCT if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) { PROC_UNLOCK(td->td_proc); return (ENOMEM); } PROC_UNLOCK(td->td_proc); +#endif } /* It looks like this was missed in r220373. --=20 Andrey Zonov --------------020105090900020700090502 Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0"; name="mlock.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="mlock.patch" Index: sys/vm/vm_map.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/vm/vm_map.c (revision 239772) +++ sys/vm/vm_map.c (working copy) @@ -3247,7 +3247,7 @@ vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm vm_offset_t bot, top; vm_size_t init_ssize; int orient, rv; - rlim_t vmemlim; + rlim_t lmemlim, vmemlim; =20 /* * The stack orientation is piggybacked with the cow argument. @@ -3267,6 +3267,7 @@ vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm init_ssize =3D (max_ssize < sgrowsiz) ? max_ssize : sgrowsiz; =20 PROC_LOCK(curthread->td_proc); + lmemlim =3D lim_cur(curthread->td_proc, RLIMIT_MEMLOCK); vmemlim =3D lim_cur(curthread->td_proc, RLIMIT_VMEM); PROC_UNLOCK(curthread->td_proc); =20 @@ -3278,6 +3279,14 @@ vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm= return (KERN_NO_SPACE); } =20 + if (map->flags & MAP_WIREFUTURE) { + if (ptoa(vmspace_wired_count(curthread->td_proc->p_vmspace)) + + init_ssize > lmemlim) { + vm_map_unlock(map); + return (KERN_NO_SPACE); + } + } + /* If we would blow our VMEM resource limit, no go */ if (map->size + init_ssize > vmemlim) { vm_map_unlock(map); @@ -3358,7 +3367,7 @@ vm_map_growstack(struct proc *p, vm_offset_t addr) vm_map_t map =3D &vm->vm_map; vm_offset_t end; size_t grow_amount, max_grow; - rlim_t stacklim, vmemlim; + rlim_t lmemlim, stacklim, vmemlim; int is_procstack, rv; struct ucred *cred; #ifdef notyet @@ -3370,6 +3379,7 @@ vm_map_growstack(struct proc *p, vm_offset_t addr) =20 Retry: PROC_LOCK(p); + lmemlim =3D lim_cur(p, RLIMIT_MEMLOCK); stacklim =3D lim_cur(p, RLIMIT_STACK); vmemlim =3D lim_cur(p, RLIMIT_VMEM); PROC_UNLOCK(p); @@ -3491,7 +3501,25 @@ Retry: if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > limit)) grow_amount =3D limit - ctob(vm->vm_ssize); #endif - + if (map->flags & MAP_WIREFUTURE) { + if (ptoa(vmspace_wired_count(p->p_vmspace)) + grow_amount > + lmemlim) { + vm_map_unlock_read(map); + rv =3D KERN_NO_SPACE; + goto out; + } +#ifdef RACCT + PROC_LOCK(p); + if (racct_set(p, RACCT_MEMLOCK, + ptoa(vmspace_wired_count(p->p_vmspace)) + grow_amount)) { + PROC_UNLOCK(p); + vm_map_unlock_read(map); + rv =3D KERN_NO_SPACE; + goto out; + } + PROC_UNLOCK(p); +#endif + } /* If we would blow our VMEM resource limit, no go */ if (map->size + grow_amount > vmemlim) { vm_map_unlock_read(map); Index: sys/vm/vm_mmap.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/vm/vm_mmap.c (revision 239772) +++ sys/vm/vm_mmap.c (working copy) @@ -1035,9 +1035,6 @@ sys_mlock(td, uap) unsigned long nsize; int error; =20 - error =3D priv_check(td, PRIV_VM_MLOCK); - if (error) - return (error); addr =3D (vm_offset_t)uap->addr; size =3D uap->len; last =3D addr + size; @@ -1102,22 +1099,18 @@ sys_mlockall(td, uap) if ((uap->how =3D=3D 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) !=3D= 0)) return (EINVAL); =20 -#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 (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 =3D priv_check(td, PRIV_VM_MLOCK); - if (error) - return (error); -#endif #ifdef RACCT PROC_LOCK(td->td_proc); error =3D racct_set(td->td_proc, RACCT_MEMLOCK, map->size); @@ -1174,9 +1167,6 @@ sys_munlockall(td, uap) int error; =20 map =3D &td->td_proc->p_vmspace->vm_map; - error =3D priv_check(td, PRIV_VM_MUNLOCK); - if (error) - return (error); =20 /* Clear the MAP_WIREFUTURE flag from this vm_map. */ vm_map_lock(map); @@ -1215,9 +1205,6 @@ sys_munlock(td, uap) vm_size_t size; int error; =20 - error =3D priv_check(td, PRIV_VM_MUNLOCK); - if (error) - return (error); addr =3D (vm_offset_t)uap->addr; size =3D uap->len; last =3D addr + size; @@ -1479,14 +1466,32 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_= t =20 if (map =3D=3D &td->td_proc->p_vmspace->vm_map) { PROC_LOCK(td->td_proc); + if (map->flags & MAP_WIREFUTURE) { + if (ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) + + size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) { + PROC_UNLOCK(td->td_proc); + return (ENOMEM); + } +#ifdef RACCT + error =3D racct_set(td->td_proc, RACCT_MEMLOCK, + ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) + + size); + if (error !=3D 0) { + PROC_UNLOCK(td->td_proc); + return (error); + } +#endif + } if (map->size + size > lim_cur(td->td_proc, RLIMIT_VMEM)) { PROC_UNLOCK(td->td_proc); return (ENOMEM); } +#ifdef RACCT /* was missed in r220373 */ if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) { PROC_UNLOCK(td->td_proc); return (ENOMEM); } +#endif PROC_UNLOCK(td->td_proc); } =20 Index: sys/vm/vm_unix.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/vm/vm_unix.c (revision 239772) +++ sys/vm/vm_unix.c (working copy) @@ -77,13 +77,14 @@ sys_obreak(td, uap) { struct vmspace *vm =3D td->td_proc->p_vmspace; vm_offset_t new, old, base; - rlim_t datalim, vmemlim; + rlim_t datalim, lmemlim, vmemlim; int prot, rv; int error =3D 0; boolean_t do_map_wirefuture; =20 PROC_LOCK(td->td_proc); datalim =3D lim_cur(td->td_proc, RLIMIT_DATA); + lmemlim =3D lim_cur(td->td_proc, RLIMIT_MEMLOCK); vmemlim =3D lim_cur(td->td_proc, RLIMIT_VMEM); PROC_UNLOCK(td->td_proc); =20 @@ -116,6 +117,13 @@ sys_obreak(td, uap) goto done; } if (new > old) { + if (vm->vm_map.flags & MAP_WIREFUTURE) { + if (ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) + + (new - old) > lmemlim) { + error =3D ENOMEM; + goto done; + } + } if (vm->vm_map.size + (new - old) > vmemlim) { error =3D ENOMEM; goto done; Index: lib/libc/sys/mlockall.2 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- lib/libc/sys/mlockall.2 (revision 239772) +++ lib/libc/sys/mlockall.2 (working copy) @@ -72,8 +72,6 @@ limit and the per-process .Dv RLIMIT_MEMLOCK resource limit. .Pp -These calls are only available to the super-user. -.Pp The .Fn munlockall call unlocks any locked memory regions in the process address space. Index: lib/libc/sys/mlock.2 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- lib/libc/sys/mlock.2 (revision 239772) +++ lib/libc/sys/mlock.2 (working copy) @@ -98,8 +98,6 @@ a system-wide ``wired pages'' limit and the per-process .Li RLIMIT_MEMLOCK resource limit. -.Pp -These calls are only available to the super-user. .Sh RETURN VALUES .Rv -std .Pp @@ -111,8 +109,6 @@ The system call will fail if: .Bl -tag -width Er -.It Bq Er EPERM -The caller is not the super-user. .It Bq Er EINVAL The address given is not page aligned or the length is negative. .It Bq Er EAGAIN @@ -128,8 +124,6 @@ The system call will fail if: .Bl -tag -width Er -.It Bq Er EPERM -The caller is not the super-user. .It Bq Er EINVAL The address given is not page aligned or the length is negative. .It Bq Er ENOMEM --------------020105090900020700090502-- --------------enig5C2551C41E5B3832AFE69806 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.18 (Darwin) Comment: GPGTools - http://gpgtools.org iQEcBAEBAgAGBQJQPy0nAAoJEBWLemxX/CvTF0QIAK0JH1n++jqx9etPFKNP8TRP lcSoyPBdzMwnpqiOPNBxJqXfrh0kW+73gyCDaPhOp65KTVIK+VPaGcZX/3qwTyA1 IdwTji8nRdwGp+L8mbjNRq/2CbHcaS/us31qql/I8krL+kJ0gfaDHOSlxuNvQj10 T3pMXQ5PmPvuioVutSrA6u1HENGCBLQemk5npvfNzDbYdwXe5re0+GhU3v7n4zoy IdX/9sDdj8skboOeVHO+n0Z9Dzr1vuTiYitfTiuy9wXhqCx2CtDOlbefWc0TEoR4 t4bNv8cnVVyXj/h7b2OdBgOOhzFtJt8jN9hjGvOMbfK6+2t17skdKcDB8R++l14= =voP9 -----END PGP SIGNATURE----- --------------enig5C2551C41E5B3832AFE69806--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?503F2D24.8050103>