From owner-freebsd-standards@FreeBSD.ORG Mon Jul 14 03:27:27 2003 Return-Path: Delivered-To: freebsd-standards@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 30C8A37B401; Mon, 14 Jul 2003 03:27:27 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id C12C743FBD; Mon, 14 Jul 2003 03:27:26 -0700 (PDT) (envelope-from kris@FreeBSD.org) Received: from freefall.freebsd.org (kris@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h6EARQUp095240; Mon, 14 Jul 2003 03:27:26 -0700 (PDT) (envelope-from kris@freefall.freebsd.org) Received: (from kris@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h6EARQkp095236; Mon, 14 Jul 2003 03:27:26 -0700 (PDT) Date: Mon, 14 Jul 2003 03:27:26 -0700 (PDT) From: Kris Kennaway Message-Id: <200307141027.h6EARQkp095236@freefall.freebsd.org> To: kris@FreeBSD.org, freebsd-bugs@FreeBSD.org, freebsd-standards@FreeBSD.org Subject: Re: standards/42617: rename(2) IEEE Std 1003.1-2001 Violation X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Jul 2003 10:27:27 -0000 Synopsis: rename(2) IEEE Std 1003.1-2001 Violation Responsible-Changed-From-To: freebsd-bugs->freebsd-standards Responsible-Changed-By: kris Responsible-Changed-When: Mon Jul 14 03:27:06 PDT 2003 Responsible-Changed-Why: Assign to standards group http://www.freebsd.org/cgi/query-pr.cgi?pr=42617 From owner-freebsd-standards@FreeBSD.ORG Mon Jul 14 11:32:08 2003 Return-Path: Delivered-To: freebsd-standards@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 224AE37B401; Mon, 14 Jul 2003 11:32:08 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id B315843FBF; Mon, 14 Jul 2003 11:32:07 -0700 (PDT) (envelope-from bde@FreeBSD.org) Received: from freefall.freebsd.org (bde@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h6EIW7Up090867; Mon, 14 Jul 2003 11:32:07 -0700 (PDT) (envelope-from bde@freefall.freebsd.org) Received: (from bde@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h6EIW7Vi090863; Mon, 14 Jul 2003 11:32:07 -0700 (PDT) Date: Mon, 14 Jul 2003 11:32:07 -0700 (PDT) From: Bruce Evans Message-Id: <200307141832.h6EIW7Vi090863@freefall.freebsd.org> To: matthias.andree@web.de, bde@FreeBSD.org, freebsd-standards@FreeBSD.org Subject: Re: standards/42617: rename(2) IEEE Std 1003.1-2001 Violation X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Jul 2003 18:32:08 -0000 Synopsis: rename(2) IEEE Std 1003.1-2001 Violation State-Changed-From-To: open->closed State-Changed-By: bde State-Changed-When: Mon Jul 14 11:26:06 PDT 2003 State-Changed-Why: Fixed in kern/vfs_syscalls.c rev.1.286 (-current) and 1.151.2.17 (RELENG_4). Many people think that the bug is in the standard, but most systems seem to follow the letter of the standard. http://www.freebsd.org/cgi/query-pr.cgi?pr=42617 From owner-freebsd-standards@FreeBSD.ORG Sat Jul 19 04:22:08 2003 Return-Path: Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2C7E237B405 for ; Sat, 19 Jul 2003 04:22:08 -0700 (PDT) Received: from hysteria.spc.org (hysteria.spc.org [195.206.69.234]) by mx1.FreeBSD.org (Postfix) with SMTP id 7ADA643F85 for ; Sat, 19 Jul 2003 04:22:04 -0700 (PDT) (envelope-from bms@hysteria.spc.org) Received: (qmail 13076 invoked by uid 5013); 19 Jul 2003 11:19:52 -0000 Date: Sat, 19 Jul 2003 12:19:52 +0100 From: Bruce M Simpson To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-standards@FreeBSD.org Message-ID: <20030719111952.GB12995@spc.org> References: <20030708152410.5E14036C@saboteur.dek.spc.org> <200307081530.h68FUDlb025977@freefall.freebsd.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="OgqxwSJOaUobr8KG" Content-Disposition: inline In-Reply-To: <200307081530.h68FUDlb025977@freefall.freebsd.org> User-Agent: Mutt/1.4.1i Organization: SPC cc: alc@freebsd.org Subject: Re: standards/54223: [PATCH] Add mlockall(), munlockall() syscalls to -CURRENT X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Jul 2003 11:22:08 -0000 --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here is an updated patch which fixes some issues. BMS --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="mlockall.patch" Revised patch to add mlockall()/munlockall() to FreeBSD 5.1-RELEASE. - Believed to back out of allocations and locks correctly (tested with WITNESS, MUTEX_PROFILING, INVARIANTS and DIAGNOSTIC). - Inspected at the vmstat, top and vm pager sysctl stats level. Paging-in activity is occurring correctly, using a test harness. - The RES size for a process may appear to be greater than its SIZE. This is believed to be due to mappings of the same shared library page being wired twice. Further exploration is needed. - All those diffs to syscalls.master for each architecture *are* necessary. This needed clarification; the stub code generation for mlockall() was disabled, which would prevent applications from linking to this API (suggested by mux@freebsd.org) - vm_map_*_all() may be eliminated and 0 no longer special (reviewed by alc@freebsd.org) - Giant has been quoshed. It is no longer held by the code, as the required locking has been pushed down within vm_map.c. Bruce M Simpson Generated by diffcoll on Sat 19 Jul 2003 00:54:30 BST diff -uN src/lib/libc/alpha/sys/Makefile.inc.orig src/lib/libc/alpha/sys/Makefile.inc --- /usr/src/lib/libc/alpha/sys/Makefile.inc.orig Fri May 30 11:25:46 2003 +++ /usr/src/lib/libc/alpha/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -5,7 +5,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/amd64/sys/Makefile.inc.orig src/lib/libc/amd64/sys/Makefile.inc --- /usr/src/lib/libc/amd64/sys/Makefile.inc.orig Fri May 30 11:26:03 2003 +++ /usr/src/lib/libc/amd64/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -6,7 +6,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/i386/sys/Makefile.inc.orig src/lib/libc/i386/sys/Makefile.inc --- /usr/src/lib/libc/i386/sys/Makefile.inc.orig Fri May 30 04:44:28 2003 +++ /usr/src/lib/libc/i386/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -9,7 +9,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/ia64/sys/Makefile.inc.orig src/lib/libc/ia64/sys/Makefile.inc --- /usr/src/lib/libc/ia64/sys/Makefile.inc.orig Fri May 30 11:26:25 2003 +++ /usr/src/lib/libc/ia64/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -5,7 +5,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/powerpc/sys/Makefile.inc.orig src/lib/libc/powerpc/sys/Makefile.inc --- /usr/src/lib/libc/powerpc/sys/Makefile.inc.orig Fri May 30 11:26:40 2003 +++ /usr/src/lib/libc/powerpc/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -4,7 +4,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/sparc64/sys/Makefile.inc.orig src/lib/libc/sparc64/sys/Makefile.inc --- /usr/src/lib/libc/sparc64/sys/Makefile.inc.orig Fri May 30 11:27:02 2003 +++ /usr/src/lib/libc/sparc64/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -16,7 +16,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/sys/Makefile.inc.orig src/lib/libc/sys/Makefile.inc --- /usr/src/lib/libc/sys/Makefile.inc.orig Sat Jun 21 10:03:26 2003 +++ /usr/src/lib/libc/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -69,8 +69,8 @@ kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \ kldunload.2 kqueue.2 kse.2 ktrace.2 link.2 lio_listio.2 listen.2 \ lseek.2 \ - madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \ - modfind.2 modnext.2 modstat.2 mount.2 \ + madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 \ + mlockall.2 mmap.2 modfind.2 modnext.2 modstat.2 mount.2 \ mprotect.2 msync.2 munmap.2 nanosleep.2 ntp_adjtime.2 ntp_gettime.2 \ nfssvc.2 open.2 pathconf.2 pipe.2 poll.2 profil.2 ptrace.2 quotactl.2 \ read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \ diff -uN src/lib/libc/sys/mlockall.2.orig src/lib/libc/sys/mlockall.2 --- /usr/src/lib/libc/sys/mlockall.2.orig Fri May 30 07:01:26 2003 +++ /usr/src/lib/libc/sys/mlockall.2 Sat Jul 19 00:52:04 2003 @@ -0,0 +1,140 @@ +.\" $NetBSD: mlockall.2,v 1.11 2003/04/16 13:34:54 wiz Exp $ +.\" +.\" Copyright (c) 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, +.\" NASA Ames Research Center. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 12, 1999 +.Dt MLOCKALL 2 +.Os +.Sh NAME +.Nm mlockall , +.Nm munlockall +.Nd lock (unlock) the address space of a process +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/mman.h +.Ft int +.Fn mlockall "int flags" +.Ft int +.Fn munlockall "void" +.Sh DESCRIPTION +The +.Nm mlockall +system call locks into memory the physical pages associated with the +address space of a process until the address space is unlocked, the +process exits, or execs another program image. +.Pp +The following flags affect the behavior of +.Nm mlockall : +.Bl -tag -width MCL_CURRENT +.It Dv MCL_CURRENT +Lock all pages currently mapped into the process's address space. +.It Dv MCL_FUTURE +Lock all pages mapped into the process's address space in the future, +at the time the mapping is established. +Note that this may cause future mappings to fail if those mappings +cause resource limits to be exceeded. +.El +.Pp +Since physical memory is a potentially scarce resource, processes are +limited in how much they can lock down. +A single process can lock the minimum of a system-wide +.Dq wired pages +limit and the per-process +.Li RLIMIT_MEMLOCK +resource limit. +.Pp +The +.Nm munlockall +call unlocks any locked memory regions in the process address space. +Any regions mapped after an +.Nm munlockall +call will not be locked. +.Sh RETURN VALUES +A return value of 0 indicates that the call +succeeded and all pages in the range have either been locked or unlocked. +A return value of -1 indicates an error occurred and the locked +status of all pages in the range remains unchanged. +In this case, the global location +.Va errno +is set to indicate the error. +.Sh ERRORS +.Fn mlockall +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Ar flags +argument is zero, or includes unimplemented flags. +.It Bq Er ENOMEM +Locking the indicated range would exceed either the system or per-process +limit for locked memory. +.It Bq Er EAGAIN +Some or all of the memory mapped into the process's address space +could not be locked when the call was made. +.It Bq Er EPERM +The calling process does not have the appropriate privilege to perform +the requested operation. +.El +.Sh SEE ALSO +.Xr mincore 2 , +.Xr mlock 2 , +.Xr mmap 2 , +.Xr munmap 2 , +.Xr setrlimit 2 +.Sh STANDARDS +The +.Fn mlockall +and +.Fn munlockall +functions are believed to conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn mlockall +and +.Fn munlockall +functions first appeared in +.Fx 5.1 . +.Sh BUGS +The per-process resource limit is a limit on the amount of virtual +memory locked, while the system-wide limit is for the number of locked +physical pages. +Hence a process with two distinct locked mappings of the same physical page +counts as 2 pages against the per-process limit and as only a single page +in the system limit. diff -uN src/sys/kern/link_elf.c.orig src/sys/kern/link_elf.c --- /usr/src/sys/kern/link_elf.c.orig Fri Jun 27 07:47:39 2003 +++ /usr/src/sys/kern/link_elf.c Sat Jul 19 00:52:04 2003 @@ -744,7 +744,7 @@ vm_map_wire(kernel_map, (vm_offset_t) segbase, (vm_offset_t) segbase + segs[i]->p_memsz, - FALSE); + VM_MAP_WIRE_SYSTEM); #endif } diff -uN src/sys/sys/mman.h.orig src/sys/sys/mman.h --- /usr/src/sys/sys/mman.h.orig Sat Jul 19 00:54:26 2003 +++ /usr/src/sys/sys/mman.h Sat Jul 19 00:53:13 2003 @@ -178,6 +178,8 @@ int munlock(const void *, size_t); int munmap(void *, size_t); #if __POSIX_VISIBLE >= 199309 +int mlockall(int); +int munlockall(void); int shm_open(const char *, int, mode_t); int shm_unlink(const char *); #endif diff -uN src/sys/vm/vm_contig.c.orig src/sys/vm/vm_contig.c --- /usr/src/sys/vm/vm_contig.c.orig Fri Jun 27 07:48:49 2003 +++ /usr/src/sys/vm/vm_contig.c Sat Jul 19 00:52:04 2003 @@ -254,7 +254,7 @@ tmp_addr += PAGE_SIZE; } VM_OBJECT_UNLOCK(kernel_object); - vm_map_wire(map, addr, addr + size, FALSE); + vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM); splx(s); return ((void *)addr); diff -uN src/sys/vm/vm_glue.c.orig src/sys/vm/vm_glue.c --- /usr/src/sys/vm/vm_glue.c.orig Fri Jun 27 07:49:23 2003 +++ /usr/src/sys/vm/vm_glue.c Sat Jul 19 00:52:04 2003 @@ -186,7 +186,7 @@ { vm_map_wire(&curproc->p_vmspace->vm_map, trunc_page((vm_offset_t)addr), - round_page((vm_offset_t)addr + len), FALSE); + round_page((vm_offset_t)addr + len), VM_MAP_WIRE_SYSTEM); } /* @@ -200,7 +200,7 @@ vm_map_unwire(&curproc->p_vmspace->vm_map, trunc_page((vm_offset_t)addr), - round_page((vm_offset_t)addr + len), FALSE); + round_page((vm_offset_t)addr + len), VM_MAP_WIRE_SYSTEM); } /* diff -uN src/sys/vm/vm_kern.c.orig src/sys/vm/vm_kern.c --- /usr/src/sys/vm/vm_kern.c.orig Fri Jun 27 07:50:53 2003 +++ /usr/src/sys/vm/vm_kern.c Sat Jul 19 00:52:04 2003 @@ -210,7 +210,7 @@ /* * And finally, mark the data as non-pageable. */ - (void) vm_map_wire(map, addr, addr + size, FALSE); + (void) vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM); return (addr); } diff -uN src/sys/vm/vm_map.c.orig src/sys/vm/vm_map.c --- /usr/src/sys/vm/vm_map.c.orig Wed Jun 4 11:01:59 2003 +++ /usr/src/sys/vm/vm_map.c Sat Jul 19 00:52:04 2003 @@ -1559,19 +1559,32 @@ */ int vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_unwire) + int flags) { vm_map_entry_t entry, first_entry, tmp_entry; vm_offset_t saved_start; unsigned int last_timestamp; int rv; boolean_t need_wakeup, result; + boolean_t user_unwire; + + user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE; vm_map_lock(map); VM_MAP_RANGE_CHECK(map, start, end); - if (!vm_map_lookup_entry(map, start, &first_entry)) { - vm_map_unlock(map); - return (KERN_INVALID_ADDRESS); + if (start != (vm_offset_t) 0) { + /* operating on arbitrary range */ + if (!vm_map_lookup_entry(map, start, &first_entry)) { + vm_map_unlock(map); + return (KERN_INVALID_ADDRESS); + } + } else { + /* operating on entire process space */ + if (map->header.next == NULL) { + vm_map_unlock(map); + return (KERN_INVALID_ADDRESS); + } + first_entry = map->header.next; } last_timestamp = map->timestamp; entry = first_entry; @@ -1627,9 +1640,11 @@ entry->eflags |= MAP_ENTRY_IN_TRANSITION; /* * Check the map for holes in the specified region. + * If VM_MAP_WIRE_NONCONTIG was specified, skip this check. */ - if (entry->end < end && (entry->next == &map->header || - entry->next->start > entry->end)) { + if (((flags & VM_MAP_WIRE_NONCONTIG) == 0) && + (entry->end < end && (entry->next == &map->header || + entry->next->start > entry->end))) { end = entry->end; rv = KERN_INVALID_ADDRESS; goto done; @@ -1688,19 +1703,25 @@ */ int vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_wire) + int flags) { vm_map_entry_t entry, first_entry, tmp_entry; vm_offset_t saved_end, saved_start; unsigned int last_timestamp; int rv; boolean_t need_wakeup, result; + boolean_t user_wire; + + user_wire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE; vm_map_lock(map); VM_MAP_RANGE_CHECK(map, start, end); if (!vm_map_lookup_entry(map, start, &first_entry)) { - vm_map_unlock(map); - return (KERN_INVALID_ADDRESS); + if ((flags & VM_MAP_WIRE_NONCONTIG) == 0) { + vm_map_unlock(map); + return (KERN_INVALID_ADDRESS); + } else + first_entry = map->header.next; } last_timestamp = map->timestamp; entry = first_entry; @@ -1811,9 +1832,11 @@ } /* * Check the map for holes in the specified region. + * If VM_MAP_WIRE_NONCONTIG was specified, skip this check. */ - if (entry->end < end && (entry->next == &map->header || - entry->next->start > entry->end)) { + if (((flags & VM_MAP_WIRE_NONCONTIG) == 0) && + (entry->end < end && (entry->next == &map->header || + entry->next->start > entry->end))) { end = entry->end; rv = KERN_INVALID_ADDRESS; goto done; @@ -2351,6 +2374,10 @@ new_map = &vm2->vm_map; /* XXX */ new_map->timestamp = 1; + /* Do not inherit the MAP_WIREFUTURE property. */ + if ((new_map->flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) + new_map->flags &= ~MAP_WIREFUTURE; + old_entry = old_map->header.next; while (old_entry != &old_map->header) { @@ -2660,6 +2687,14 @@ } vm_map_unlock(map); + /* + * Heed the MAP_WIREFUTURE flag if it was set for this process. + */ + if (rv == KERN_SUCCESS && (map->flags & MAP_WIREFUTURE)) + vm_map_wire(map, addr, stack_entry->start, + (p->p_flag & P_SYSTEM ? VM_MAP_WIRE_SYSTEM : + VM_MAP_WIRE_USER)); + return (rv); } diff -uN src/sys/vm/vm_map.h.orig src/sys/vm/vm_map.h --- /usr/src/sys/vm/vm_map.h.orig Wed Jun 4 13:45:35 2003 +++ /usr/src/sys/vm/vm_map.h Sat Jul 19 00:52:04 2003 @@ -81,6 +81,7 @@ * vm_map_entry_t an entry in an address map. */ +typedef u_int vm_flags_t; typedef u_int vm_eflags_t; /* @@ -177,8 +178,11 @@ pmap_t pmap; /* (c) Physical map */ #define min_offset header.start /* (c) */ #define max_offset header.end /* (c) */ + vm_flags_t flags; /* flags for this vm_map */ }; +#define MAP_WIREFUTURE 0x0001 /* wire all future pages */ + #ifdef _KERNEL static __inline vm_offset_t vm_map_max(vm_map_t map) @@ -197,6 +201,12 @@ { return (map->pmap); } + +static __inline void +vm_map_modflags(vm_map_t map, vm_flags_t set, vm_flags_t clear) +{ + map->flags = (map->flags | set) & ~clear; +} #endif /* _KERNEL */ /* @@ -296,6 +306,13 @@ #define VM_FAULT_WIRE_MASK (VM_FAULT_CHANGE_WIRING|VM_FAULT_USER_WIRE) #define VM_FAULT_DIRTY 8 /* Dirty the page */ +/* + * vm_map_[un]wire option flags + */ +#define VM_MAP_WIRE_SYSTEM 0 /* wiring in a kernel map */ +#define VM_MAP_WIRE_USER 1 /* wiring in a user map */ +#define VM_MAP_WIRE_NONCONTIG 2 /* requested region has holes */ + #ifdef _KERNEL boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t); struct pmap; @@ -321,9 +338,9 @@ int vm_map_stack (vm_map_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int); int vm_map_growstack (struct proc *p, vm_offset_t addr); int vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_unwire); + int flags); int vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_wire); + int flags); int vmspace_swap_count (struct vmspace *vmspace); #endif /* _KERNEL */ #endif /* _VM_MAP_ */ diff -uN src/sys/vm/vm_mmap.c.orig src/sys/vm/vm_mmap.c --- /usr/src/sys/vm/vm_mmap.c.orig Fri Jun 27 08:32:54 2003 +++ /usr/src/sys/vm/vm_mmap.c Sat Jul 19 00:52:04 2003 @@ -1039,7 +1039,7 @@ #endif error = vm_map_wire(&td->td_proc->p_vmspace->vm_map, addr, - addr + size, TRUE); + addr + size, VM_MAP_WIRE_USER); return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1057,14 +1057,55 @@ struct thread *td; struct mlockall_args *uap; { - /* mtx_lock(&Giant); */ - /* mtx_unlock(&Giant); */ - return 0; + int error; + vm_map_t map; + + error = 0; + map = &td->td_proc->p_vmspace->vm_map; + + if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0)) + return (EINVAL); + +#ifdef pmap_wired_count + /* + * If wiring all pages in the process would cause it to exceed + * a hard resource limit, return ENOMEM. + */ + if (map->size - ptoa(pmap_wired_count(vm_map_pmap(map)) > + td->td_proc->p_rlimit[RLIMIT_MEMLOCK].rlim_cur)) + return (ENOMEM); +#else + error = suser(td); + if (error) + return (error); +#endif + + if (uap->how & MCL_FUTURE) { + vm_map_lock(map); + vm_map_modflags(map, MAP_WIREFUTURE, 0); + vm_map_unlock(map); + error = 0; + } + + if (uap->how & MCL_CURRENT) { + /* + * P1003.1-2001 actually mandates that all currently + * mapped pages will be memory resident and locked (wired). + * This implies that we need to prefault. However, the act + * of wiring the page will incur a call to vm_fault_wire(), + * which will fault in the newly wired page. + */ + error = vm_map_wire(map, vm_map_min(map), vm_map_max(map), + VM_MAP_WIRE_USER|VM_MAP_WIRE_NONCONTIG); + error = (error == KERN_SUCCESS ? 0 : EAGAIN); + } + + return (error); } #ifndef _SYS_SYSPROTO_H_ struct munlockall_args { - int how; + register_t dummy; }; #endif @@ -1076,9 +1117,27 @@ struct thread *td; struct munlockall_args *uap; { - /* mtx_lock(&Giant); */ - /* mtx_unlock(&Giant); */ - return 0; + int error; + vm_map_t map; + +#ifndef pmap_wired_count + error = suser(td); + if (error) + return (error); +#endif + error = 0; + map = &td->td_proc->p_vmspace->vm_map; + + /* Clear the MAP_WIREFUTURE flag from this vm_map. */ + vm_map_lock(map); + vm_map_modflags(map, 0, MAP_WIREFUTURE); + vm_map_unlock(map); + + /* Forcibly unwire all pages. */ + error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map), + VM_MAP_WIRE_USER|VM_MAP_WIRE_NONCONTIG); + + return (error); } #ifndef _SYS_SYSPROTO_H_ @@ -1118,7 +1177,7 @@ #endif error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, addr, - addr + size, TRUE); + addr + size, VM_MAP_WIRE_USER); return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1275,6 +1334,14 @@ if (rv != KERN_SUCCESS) (void) vm_map_remove(map, *addr, *addr + size); } + + /* + * If the process has requested that all future mappings + * be wired, then heed this. + */ + if ((rv == KERN_SUCCESS) && (map->flags & MAP_WIREFUTURE)) + vm_map_wire(map, *addr, *addr + size, VM_MAP_WIRE_USER); + switch (rv) { case KERN_SUCCESS: return (0); diff -uN src/sys/vm/vm_unix.c.orig src/sys/vm/vm_unix.c --- /usr/src/sys/vm/vm_unix.c.orig Wed Jun 4 22:40:38 2003 +++ /usr/src/sys/vm/vm_unix.c Sat Jul 19 00:52:04 2003 @@ -77,6 +77,9 @@ vm_offset_t new, old, base; int rv; int error = 0; + boolean_t do_map_wirefuture; + + do_map_wirefuture = FALSE; new = round_page((vm_offset_t)uap->nsize); vm_map_lock(&vm->vm_map); @@ -119,6 +122,21 @@ goto done; } vm->vm_dsize += btoc(new - old); + /* + * Handle the MAP_WIREFUTURE case for legacy applications, + * by marking the newly mapped range of pages as wired. + * + * We are not required to perform a corresponding + * vm_map_unwire() before vm_map_delete() below, as + * it will forcibly unwire the pages in the range. + * + * XXX If the pages cannot be wired, no error is returned. + */ + if ((vm->vm_map.flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) { + if (bootverbose) + printf("obreak: MAP_WIREFUTURE set\n"); + do_map_wirefuture = TRUE; + } } else if (new < old) { rv = vm_map_delete(&vm->vm_map, new, old); if (rv != KERN_SUCCESS) { @@ -129,6 +147,10 @@ } done: vm_map_unlock(&vm->vm_map); + + if (do_map_wirefuture) + (void) vm_map_wire(&vm->vm_map, old, new, VM_MAP_WIRE_USER); + return (error); } --OgqxwSJOaUobr8KG-- From owner-freebsd-standards@FreeBSD.ORG Sat Jul 19 04:30:17 2003 Return-Path: Delivered-To: freebsd-standards@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A5CCC37B401 for ; Sat, 19 Jul 2003 04:30:17 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id A617443F3F for ; Sat, 19 Jul 2003 04:30:16 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h6JBUGUp098759 for ; Sat, 19 Jul 2003 04:30:16 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h6JBUGMp098758; Sat, 19 Jul 2003 04:30:16 -0700 (PDT) Date: Sat, 19 Jul 2003 04:30:16 -0700 (PDT) Message-Id: <200307191130.h6JBUGMp098758@freefall.freebsd.org> To: freebsd-standards@FreeBSD.org From: Bruce M Simpson Subject: Re: standards/54223: [PATCH] Add mlockall(), munlockall() syscalls to -CURRENT X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Bruce M Simpson List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Jul 2003 11:30:18 -0000 The following reply was made to PR standards/54223; it has been noted by GNATS. From: Bruce M Simpson To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-standards@FreeBSD.org Cc: alc@freebsd.org Subject: Re: standards/54223: [PATCH] Add mlockall(), munlockall() syscalls to -CURRENT Date: Sat, 19 Jul 2003 12:19:52 +0100 --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here is an updated patch which fixes some issues. BMS --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="mlockall.patch" Revised patch to add mlockall()/munlockall() to FreeBSD 5.1-RELEASE. - Believed to back out of allocations and locks correctly (tested with WITNESS, MUTEX_PROFILING, INVARIANTS and DIAGNOSTIC). - Inspected at the vmstat, top and vm pager sysctl stats level. Paging-in activity is occurring correctly, using a test harness. - The RES size for a process may appear to be greater than its SIZE. This is believed to be due to mappings of the same shared library page being wired twice. Further exploration is needed. - All those diffs to syscalls.master for each architecture *are* necessary. This needed clarification; the stub code generation for mlockall() was disabled, which would prevent applications from linking to this API (suggested by mux@freebsd.org) - vm_map_*_all() may be eliminated and 0 no longer special (reviewed by alc@freebsd.org) - Giant has been quoshed. It is no longer held by the code, as the required locking has been pushed down within vm_map.c. Bruce M Simpson Generated by diffcoll on Sat 19 Jul 2003 00:54:30 BST diff -uN src/lib/libc/alpha/sys/Makefile.inc.orig src/lib/libc/alpha/sys/Makefile.inc --- /usr/src/lib/libc/alpha/sys/Makefile.inc.orig Fri May 30 11:25:46 2003 +++ /usr/src/lib/libc/alpha/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -5,7 +5,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/amd64/sys/Makefile.inc.orig src/lib/libc/amd64/sys/Makefile.inc --- /usr/src/lib/libc/amd64/sys/Makefile.inc.orig Fri May 30 11:26:03 2003 +++ /usr/src/lib/libc/amd64/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -6,7 +6,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/i386/sys/Makefile.inc.orig src/lib/libc/i386/sys/Makefile.inc --- /usr/src/lib/libc/i386/sys/Makefile.inc.orig Fri May 30 04:44:28 2003 +++ /usr/src/lib/libc/i386/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -9,7 +9,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/ia64/sys/Makefile.inc.orig src/lib/libc/ia64/sys/Makefile.inc --- /usr/src/lib/libc/ia64/sys/Makefile.inc.orig Fri May 30 11:26:25 2003 +++ /usr/src/lib/libc/ia64/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -5,7 +5,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o vfork.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/powerpc/sys/Makefile.inc.orig src/lib/libc/powerpc/sys/Makefile.inc --- /usr/src/lib/libc/powerpc/sys/Makefile.inc.orig Fri May 30 11:26:40 2003 +++ /usr/src/lib/libc/powerpc/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -4,7 +4,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/sparc64/sys/Makefile.inc.orig src/lib/libc/sparc64/sys/Makefile.inc --- /usr/src/lib/libc/sparc64/sys/Makefile.inc.orig Fri May 30 11:27:02 2003 +++ /usr/src/lib/libc/sparc64/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -16,7 +16,7 @@ # Don't generate default code for these syscalls: NOASM= break.o exit.o ftruncate.o getdomainname.o getlogin.o \ - lseek.o mlockall.o mmap.o munlockall.o openbsd_poll.o pread.o \ + lseek.o mmap.o openbsd_poll.o pread.o \ pwrite.o setdomainname.o sstk.o truncate.o uname.o yield.o PSEUDO= _getlogin.o _exit.o diff -uN src/lib/libc/sys/Makefile.inc.orig src/lib/libc/sys/Makefile.inc --- /usr/src/lib/libc/sys/Makefile.inc.orig Sat Jun 21 10:03:26 2003 +++ /usr/src/lib/libc/sys/Makefile.inc Sat Jul 19 00:52:04 2003 @@ -69,8 +69,8 @@ kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \ kldunload.2 kqueue.2 kse.2 ktrace.2 link.2 lio_listio.2 listen.2 \ lseek.2 \ - madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \ - modfind.2 modnext.2 modstat.2 mount.2 \ + madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 \ + mlockall.2 mmap.2 modfind.2 modnext.2 modstat.2 mount.2 \ mprotect.2 msync.2 munmap.2 nanosleep.2 ntp_adjtime.2 ntp_gettime.2 \ nfssvc.2 open.2 pathconf.2 pipe.2 poll.2 profil.2 ptrace.2 quotactl.2 \ read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \ diff -uN src/lib/libc/sys/mlockall.2.orig src/lib/libc/sys/mlockall.2 --- /usr/src/lib/libc/sys/mlockall.2.orig Fri May 30 07:01:26 2003 +++ /usr/src/lib/libc/sys/mlockall.2 Sat Jul 19 00:52:04 2003 @@ -0,0 +1,140 @@ +.\" $NetBSD: mlockall.2,v 1.11 2003/04/16 13:34:54 wiz Exp $ +.\" +.\" Copyright (c) 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, +.\" NASA Ames Research Center. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 12, 1999 +.Dt MLOCKALL 2 +.Os +.Sh NAME +.Nm mlockall , +.Nm munlockall +.Nd lock (unlock) the address space of a process +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/mman.h +.Ft int +.Fn mlockall "int flags" +.Ft int +.Fn munlockall "void" +.Sh DESCRIPTION +The +.Nm mlockall +system call locks into memory the physical pages associated with the +address space of a process until the address space is unlocked, the +process exits, or execs another program image. +.Pp +The following flags affect the behavior of +.Nm mlockall : +.Bl -tag -width MCL_CURRENT +.It Dv MCL_CURRENT +Lock all pages currently mapped into the process's address space. +.It Dv MCL_FUTURE +Lock all pages mapped into the process's address space in the future, +at the time the mapping is established. +Note that this may cause future mappings to fail if those mappings +cause resource limits to be exceeded. +.El +.Pp +Since physical memory is a potentially scarce resource, processes are +limited in how much they can lock down. +A single process can lock the minimum of a system-wide +.Dq wired pages +limit and the per-process +.Li RLIMIT_MEMLOCK +resource limit. +.Pp +The +.Nm munlockall +call unlocks any locked memory regions in the process address space. +Any regions mapped after an +.Nm munlockall +call will not be locked. +.Sh RETURN VALUES +A return value of 0 indicates that the call +succeeded and all pages in the range have either been locked or unlocked. +A return value of -1 indicates an error occurred and the locked +status of all pages in the range remains unchanged. +In this case, the global location +.Va errno +is set to indicate the error. +.Sh ERRORS +.Fn mlockall +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Ar flags +argument is zero, or includes unimplemented flags. +.It Bq Er ENOMEM +Locking the indicated range would exceed either the system or per-process +limit for locked memory. +.It Bq Er EAGAIN +Some or all of the memory mapped into the process's address space +could not be locked when the call was made. +.It Bq Er EPERM +The calling process does not have the appropriate privilege to perform +the requested operation. +.El +.Sh SEE ALSO +.Xr mincore 2 , +.Xr mlock 2 , +.Xr mmap 2 , +.Xr munmap 2 , +.Xr setrlimit 2 +.Sh STANDARDS +The +.Fn mlockall +and +.Fn munlockall +functions are believed to conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn mlockall +and +.Fn munlockall +functions first appeared in +.Fx 5.1 . +.Sh BUGS +The per-process resource limit is a limit on the amount of virtual +memory locked, while the system-wide limit is for the number of locked +physical pages. +Hence a process with two distinct locked mappings of the same physical page +counts as 2 pages against the per-process limit and as only a single page +in the system limit. diff -uN src/sys/kern/link_elf.c.orig src/sys/kern/link_elf.c --- /usr/src/sys/kern/link_elf.c.orig Fri Jun 27 07:47:39 2003 +++ /usr/src/sys/kern/link_elf.c Sat Jul 19 00:52:04 2003 @@ -744,7 +744,7 @@ vm_map_wire(kernel_map, (vm_offset_t) segbase, (vm_offset_t) segbase + segs[i]->p_memsz, - FALSE); + VM_MAP_WIRE_SYSTEM); #endif } diff -uN src/sys/sys/mman.h.orig src/sys/sys/mman.h --- /usr/src/sys/sys/mman.h.orig Sat Jul 19 00:54:26 2003 +++ /usr/src/sys/sys/mman.h Sat Jul 19 00:53:13 2003 @@ -178,6 +178,8 @@ int munlock(const void *, size_t); int munmap(void *, size_t); #if __POSIX_VISIBLE >= 199309 +int mlockall(int); +int munlockall(void); int shm_open(const char *, int, mode_t); int shm_unlink(const char *); #endif diff -uN src/sys/vm/vm_contig.c.orig src/sys/vm/vm_contig.c --- /usr/src/sys/vm/vm_contig.c.orig Fri Jun 27 07:48:49 2003 +++ /usr/src/sys/vm/vm_contig.c Sat Jul 19 00:52:04 2003 @@ -254,7 +254,7 @@ tmp_addr += PAGE_SIZE; } VM_OBJECT_UNLOCK(kernel_object); - vm_map_wire(map, addr, addr + size, FALSE); + vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM); splx(s); return ((void *)addr); diff -uN src/sys/vm/vm_glue.c.orig src/sys/vm/vm_glue.c --- /usr/src/sys/vm/vm_glue.c.orig Fri Jun 27 07:49:23 2003 +++ /usr/src/sys/vm/vm_glue.c Sat Jul 19 00:52:04 2003 @@ -186,7 +186,7 @@ { vm_map_wire(&curproc->p_vmspace->vm_map, trunc_page((vm_offset_t)addr), - round_page((vm_offset_t)addr + len), FALSE); + round_page((vm_offset_t)addr + len), VM_MAP_WIRE_SYSTEM); } /* @@ -200,7 +200,7 @@ vm_map_unwire(&curproc->p_vmspace->vm_map, trunc_page((vm_offset_t)addr), - round_page((vm_offset_t)addr + len), FALSE); + round_page((vm_offset_t)addr + len), VM_MAP_WIRE_SYSTEM); } /* diff -uN src/sys/vm/vm_kern.c.orig src/sys/vm/vm_kern.c --- /usr/src/sys/vm/vm_kern.c.orig Fri Jun 27 07:50:53 2003 +++ /usr/src/sys/vm/vm_kern.c Sat Jul 19 00:52:04 2003 @@ -210,7 +210,7 @@ /* * And finally, mark the data as non-pageable. */ - (void) vm_map_wire(map, addr, addr + size, FALSE); + (void) vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM); return (addr); } diff -uN src/sys/vm/vm_map.c.orig src/sys/vm/vm_map.c --- /usr/src/sys/vm/vm_map.c.orig Wed Jun 4 11:01:59 2003 +++ /usr/src/sys/vm/vm_map.c Sat Jul 19 00:52:04 2003 @@ -1559,19 +1559,32 @@ */ int vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_unwire) + int flags) { vm_map_entry_t entry, first_entry, tmp_entry; vm_offset_t saved_start; unsigned int last_timestamp; int rv; boolean_t need_wakeup, result; + boolean_t user_unwire; + + user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE; vm_map_lock(map); VM_MAP_RANGE_CHECK(map, start, end); - if (!vm_map_lookup_entry(map, start, &first_entry)) { - vm_map_unlock(map); - return (KERN_INVALID_ADDRESS); + if (start != (vm_offset_t) 0) { + /* operating on arbitrary range */ + if (!vm_map_lookup_entry(map, start, &first_entry)) { + vm_map_unlock(map); + return (KERN_INVALID_ADDRESS); + } + } else { + /* operating on entire process space */ + if (map->header.next == NULL) { + vm_map_unlock(map); + return (KERN_INVALID_ADDRESS); + } + first_entry = map->header.next; } last_timestamp = map->timestamp; entry = first_entry; @@ -1627,9 +1640,11 @@ entry->eflags |= MAP_ENTRY_IN_TRANSITION; /* * Check the map for holes in the specified region. + * If VM_MAP_WIRE_NONCONTIG was specified, skip this check. */ - if (entry->end < end && (entry->next == &map->header || - entry->next->start > entry->end)) { + if (((flags & VM_MAP_WIRE_NONCONTIG) == 0) && + (entry->end < end && (entry->next == &map->header || + entry->next->start > entry->end))) { end = entry->end; rv = KERN_INVALID_ADDRESS; goto done; @@ -1688,19 +1703,25 @@ */ int vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_wire) + int flags) { vm_map_entry_t entry, first_entry, tmp_entry; vm_offset_t saved_end, saved_start; unsigned int last_timestamp; int rv; boolean_t need_wakeup, result; + boolean_t user_wire; + + user_wire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE; vm_map_lock(map); VM_MAP_RANGE_CHECK(map, start, end); if (!vm_map_lookup_entry(map, start, &first_entry)) { - vm_map_unlock(map); - return (KERN_INVALID_ADDRESS); + if ((flags & VM_MAP_WIRE_NONCONTIG) == 0) { + vm_map_unlock(map); + return (KERN_INVALID_ADDRESS); + } else + first_entry = map->header.next; } last_timestamp = map->timestamp; entry = first_entry; @@ -1811,9 +1832,11 @@ } /* * Check the map for holes in the specified region. + * If VM_MAP_WIRE_NONCONTIG was specified, skip this check. */ - if (entry->end < end && (entry->next == &map->header || - entry->next->start > entry->end)) { + if (((flags & VM_MAP_WIRE_NONCONTIG) == 0) && + (entry->end < end && (entry->next == &map->header || + entry->next->start > entry->end))) { end = entry->end; rv = KERN_INVALID_ADDRESS; goto done; @@ -2351,6 +2374,10 @@ new_map = &vm2->vm_map; /* XXX */ new_map->timestamp = 1; + /* Do not inherit the MAP_WIREFUTURE property. */ + if ((new_map->flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) + new_map->flags &= ~MAP_WIREFUTURE; + old_entry = old_map->header.next; while (old_entry != &old_map->header) { @@ -2660,6 +2687,14 @@ } vm_map_unlock(map); + /* + * Heed the MAP_WIREFUTURE flag if it was set for this process. + */ + if (rv == KERN_SUCCESS && (map->flags & MAP_WIREFUTURE)) + vm_map_wire(map, addr, stack_entry->start, + (p->p_flag & P_SYSTEM ? VM_MAP_WIRE_SYSTEM : + VM_MAP_WIRE_USER)); + return (rv); } diff -uN src/sys/vm/vm_map.h.orig src/sys/vm/vm_map.h --- /usr/src/sys/vm/vm_map.h.orig Wed Jun 4 13:45:35 2003 +++ /usr/src/sys/vm/vm_map.h Sat Jul 19 00:52:04 2003 @@ -81,6 +81,7 @@ * vm_map_entry_t an entry in an address map. */ +typedef u_int vm_flags_t; typedef u_int vm_eflags_t; /* @@ -177,8 +178,11 @@ pmap_t pmap; /* (c) Physical map */ #define min_offset header.start /* (c) */ #define max_offset header.end /* (c) */ + vm_flags_t flags; /* flags for this vm_map */ }; +#define MAP_WIREFUTURE 0x0001 /* wire all future pages */ + #ifdef _KERNEL static __inline vm_offset_t vm_map_max(vm_map_t map) @@ -197,6 +201,12 @@ { return (map->pmap); } + +static __inline void +vm_map_modflags(vm_map_t map, vm_flags_t set, vm_flags_t clear) +{ + map->flags = (map->flags | set) & ~clear; +} #endif /* _KERNEL */ /* @@ -296,6 +306,13 @@ #define VM_FAULT_WIRE_MASK (VM_FAULT_CHANGE_WIRING|VM_FAULT_USER_WIRE) #define VM_FAULT_DIRTY 8 /* Dirty the page */ +/* + * vm_map_[un]wire option flags + */ +#define VM_MAP_WIRE_SYSTEM 0 /* wiring in a kernel map */ +#define VM_MAP_WIRE_USER 1 /* wiring in a user map */ +#define VM_MAP_WIRE_NONCONTIG 2 /* requested region has holes */ + #ifdef _KERNEL boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t); struct pmap; @@ -321,9 +338,9 @@ int vm_map_stack (vm_map_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int); int vm_map_growstack (struct proc *p, vm_offset_t addr); int vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_unwire); + int flags); int vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, - boolean_t user_wire); + int flags); int vmspace_swap_count (struct vmspace *vmspace); #endif /* _KERNEL */ #endif /* _VM_MAP_ */ diff -uN src/sys/vm/vm_mmap.c.orig src/sys/vm/vm_mmap.c --- /usr/src/sys/vm/vm_mmap.c.orig Fri Jun 27 08:32:54 2003 +++ /usr/src/sys/vm/vm_mmap.c Sat Jul 19 00:52:04 2003 @@ -1039,7 +1039,7 @@ #endif error = vm_map_wire(&td->td_proc->p_vmspace->vm_map, addr, - addr + size, TRUE); + addr + size, VM_MAP_WIRE_USER); return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1057,14 +1057,55 @@ struct thread *td; struct mlockall_args *uap; { - /* mtx_lock(&Giant); */ - /* mtx_unlock(&Giant); */ - return 0; + int error; + vm_map_t map; + + error = 0; + map = &td->td_proc->p_vmspace->vm_map; + + if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0)) + return (EINVAL); + +#ifdef pmap_wired_count + /* + * If wiring all pages in the process would cause it to exceed + * a hard resource limit, return ENOMEM. + */ + if (map->size - ptoa(pmap_wired_count(vm_map_pmap(map)) > + td->td_proc->p_rlimit[RLIMIT_MEMLOCK].rlim_cur)) + return (ENOMEM); +#else + error = suser(td); + if (error) + return (error); +#endif + + if (uap->how & MCL_FUTURE) { + vm_map_lock(map); + vm_map_modflags(map, MAP_WIREFUTURE, 0); + vm_map_unlock(map); + error = 0; + } + + if (uap->how & MCL_CURRENT) { + /* + * P1003.1-2001 actually mandates that all currently + * mapped pages will be memory resident and locked (wired). + * This implies that we need to prefault. However, the act + * of wiring the page will incur a call to vm_fault_wire(), + * which will fault in the newly wired page. + */ + error = vm_map_wire(map, vm_map_min(map), vm_map_max(map), + VM_MAP_WIRE_USER|VM_MAP_WIRE_NONCONTIG); + error = (error == KERN_SUCCESS ? 0 : EAGAIN); + } + + return (error); } #ifndef _SYS_SYSPROTO_H_ struct munlockall_args { - int how; + register_t dummy; }; #endif @@ -1076,9 +1117,27 @@ struct thread *td; struct munlockall_args *uap; { - /* mtx_lock(&Giant); */ - /* mtx_unlock(&Giant); */ - return 0; + int error; + vm_map_t map; + +#ifndef pmap_wired_count + error = suser(td); + if (error) + return (error); +#endif + error = 0; + map = &td->td_proc->p_vmspace->vm_map; + + /* Clear the MAP_WIREFUTURE flag from this vm_map. */ + vm_map_lock(map); + vm_map_modflags(map, 0, MAP_WIREFUTURE); + vm_map_unlock(map); + + /* Forcibly unwire all pages. */ + error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map), + VM_MAP_WIRE_USER|VM_MAP_WIRE_NONCONTIG); + + return (error); } #ifndef _SYS_SYSPROTO_H_ @@ -1118,7 +1177,7 @@ #endif error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, addr, - addr + size, TRUE); + addr + size, VM_MAP_WIRE_USER); return (error == KERN_SUCCESS ? 0 : ENOMEM); } @@ -1275,6 +1334,14 @@ if (rv != KERN_SUCCESS) (void) vm_map_remove(map, *addr, *addr + size); } + + /* + * If the process has requested that all future mappings + * be wired, then heed this. + */ + if ((rv == KERN_SUCCESS) && (map->flags & MAP_WIREFUTURE)) + vm_map_wire(map, *addr, *addr + size, VM_MAP_WIRE_USER); + switch (rv) { case KERN_SUCCESS: return (0); diff -uN src/sys/vm/vm_unix.c.orig src/sys/vm/vm_unix.c --- /usr/src/sys/vm/vm_unix.c.orig Wed Jun 4 22:40:38 2003 +++ /usr/src/sys/vm/vm_unix.c Sat Jul 19 00:52:04 2003 @@ -77,6 +77,9 @@ vm_offset_t new, old, base; int rv; int error = 0; + boolean_t do_map_wirefuture; + + do_map_wirefuture = FALSE; new = round_page((vm_offset_t)uap->nsize); vm_map_lock(&vm->vm_map); @@ -119,6 +122,21 @@ goto done; } vm->vm_dsize += btoc(new - old); + /* + * Handle the MAP_WIREFUTURE case for legacy applications, + * by marking the newly mapped range of pages as wired. + * + * We are not required to perform a corresponding + * vm_map_unwire() before vm_map_delete() below, as + * it will forcibly unwire the pages in the range. + * + * XXX If the pages cannot be wired, no error is returned. + */ + if ((vm->vm_map.flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) { + if (bootverbose) + printf("obreak: MAP_WIREFUTURE set\n"); + do_map_wirefuture = TRUE; + } } else if (new < old) { rv = vm_map_delete(&vm->vm_map, new, old); if (rv != KERN_SUCCESS) { @@ -129,6 +147,10 @@ } done: vm_map_unlock(&vm->vm_map); + + if (do_map_wirefuture) + (void) vm_map_wire(&vm->vm_map, old, new, VM_MAP_WIRE_USER); + return (error); } --OgqxwSJOaUobr8KG-- From owner-freebsd-standards@FreeBSD.ORG Sat Jul 19 05:20:15 2003 Return-Path: Delivered-To: freebsd-standards@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3B8BD37B401 for ; Sat, 19 Jul 2003 05:20:15 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1212543F85 for ; Sat, 19 Jul 2003 05:20:14 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h6JCKDUp009683 for ; Sat, 19 Jul 2003 05:20:13 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h6JCKD1Z009682; Sat, 19 Jul 2003 05:20:13 -0700 (PDT) Resent-Date: Sat, 19 Jul 2003 05:20:13 -0700 (PDT) Resent-Message-Id: <200307191220.h6JCKD1Z009682@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-standards@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Bruce M Simpson Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id ABEE937B401 for ; Sat, 19 Jul 2003 05:17:04 -0700 (PDT) Received: from bigboy.spc.org (bigboy.spc.org [195.206.69.225]) by mx1.FreeBSD.org (Postfix) with ESMTP id 36EF343FA3 for ; Sat, 19 Jul 2003 05:17:03 -0700 (PDT) (envelope-from bms@spc.org) Received: from saboteur.dek.spc.org (unknown [81.3.72.68]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by bigboy.spc.org (Postfix) with ESMTP id 7E1A2316A for ; Sat, 19 Jul 2003 13:17:11 +0100 (BST) Received: by saboteur.dek.spc.org (Postfix, from userid 1001) id C047F933; Sat, 19 Jul 2003 13:17:00 +0100 (BST) Message-Id: <20030719121700.C047F933@saboteur.dek.spc.org> Date: Sat, 19 Jul 2003 13:17:00 +0100 (BST) From: Bruce M Simpson To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: standards/54634: [PATCH] add posix_madvise() call to -CURRENT X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Bruce M Simpson List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Jul 2003 12:20:15 -0000 >Number: 54634 >Category: standards >Synopsis: [PATCH] add posix_madvise() call to -CURRENT >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-standards >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sat Jul 19 05:20:13 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Bruce M Simpson >Release: FreeBSD 5.1-RELEASE i386 >Organization: >Environment: System: FreeBSD saboteur.dek.spc.org 5.1-RELEASE FreeBSD 5.1-RELEASE #3: Mon Jun 23 06:55:01 BST 2003 root@saboteur.dek.spc.org:/usr/src/sys/i386/compile/SABOTEUR i386 >Description: Here is a patch to add posix_madvise() -part of the POSIX/C99 conformance project. >How-To-Repeat: >Fix: --- posix_madvise.patch begins here --- Generated by diffcoll on Sat 21 Jun 2003 10:22:04 BST diff -uN src/sys/sys/mman.h.orig src/sys/sys/mman.h --- /usr/src/sys/sys/mman.h.orig Sat Jun 21 09:57:14 2003 +++ /usr/src/sys/sys/mman.h Sat Jun 21 09:59:13 2003 @@ -125,6 +125,11 @@ #define MADV_NOCORE 8 /* do not include these pages in a core file */ #define MADV_CORE 9 /* revert to including pages in a core file */ #define MADV_PROTECT 10 /* protect process from pageout kill */ +#define POSIX_MADV_NORMAL MADV_NORMAL +#define POSIX_MADV_RANDOM MADV_RANDOM +#define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL +#define POSIX_MADV_WILLNEED MADV_WILLNEED +#define POSIX_MADV_DONTNEED MADV_DONTNEED /* * Return bits from mincore @@ -160,7 +165,7 @@ __BEGIN_DECLS /* - * XXX not yet implemented: mlockall(), munlockall(), posix_madvise(), + * XXX not yet implemented: mlockall(), munlockall(), * posix_mem_offset(), posix_typed_mem_get_info(), posix_typed_mem_open(). */ #if __BSD_VISIBLE @@ -178,6 +183,7 @@ int munlock(const void *, size_t); int munmap(void *, size_t); #if __POSIX_VISIBLE >= 199309 +int posix_madvise(void *, size_t, int); int shm_open(const char *, int, mode_t); int shm_unlink(const char *); #endif diff -uN src/lib/libc/gen/Makefile.inc.orig src/lib/libc/gen/Makefile.inc --- /usr/src/lib/libc/gen/Makefile.inc.orig Sat Jun 21 10:02:13 2003 +++ /usr/src/lib/libc/gen/Makefile.inc Sat Jun 21 10:02:56 2003 @@ -19,7 +19,8 @@ initgroups.c isatty.c jrand48.c lcong48.c \ lockf.c lrand48.c mrand48.c nice.c \ nlist.c nrand48.c ntp_gettime.c opendir.c \ - pause.c popen.c posixshm.c pselect.c psignal.c pw_scan.c pwcache.c \ + pause.c popen.c posixshm.c pmadvise.c \ + pselect.c psignal.c pw_scan.c pwcache.c \ raise.c readdir.c readpassphrase.c rewinddir.c \ scandir.c seed48.c seekdir.c semctl.c \ setdomainname.c sethostname.c setjmperr.c setmode.c \ diff -uN src/lib/libc/gen/pmadvise.c.orig src/lib/libc/gen/pmadvise.c --- /usr/src/lib/libc/gen/pmadvise.c.orig Fri Feb 1 00:57:29 2002 +++ /usr/src/lib/libc/gen/pmadvise.c Sat Jun 21 10:01:39 2003 @@ -1,7 +1,7 @@ /* * The contents of this file are in the public domain. * Written by Garrett A. Wollman, 2000-10-07. - * + * Updated by Bruce M. Simpson, 2003-06-21. */ #include @@ -10,7 +10,7 @@ #include int -(posix_madvise)(void *address, size_t size, int how) +posix_madvise(void *addr, size_t len, int advice) { - return posix_madvise(address, size, how); + return madvise(addr, len, advice); } diff -uN src/lib/libc/sys/Makefile.inc.orig src/lib/libc/sys/Makefile.inc --- /usr/src/lib/libc/sys/Makefile.inc.orig Sat Jun 21 10:03:26 2003 +++ /usr/src/lib/libc/sys/Makefile.inc Sat Jun 21 10:04:04 2003 @@ -119,6 +119,7 @@ MLINKS+=kqueue.2 kevent.2 MLINKS+=kse.2 kse_create.2 kse.2 kse_exit.2 kse.2 kse_release.2 \ kse.2 kse_wakeup.2 kse.2 kse_thr_interrupt.2 +MLINKS+=madvise.2 posix_madvise.2 MLINKS+=mlock.2 munlock.2 MLINKS+=modnext.2 modfnext.2 MLINKS+=mount.2 unmount.2 diff -uN src/lib/libc/sys/madvise.2.orig src/lib/libc/sys/madvise.2 --- /usr/src/lib/libc/sys/madvise.2.orig Sat Jun 21 10:04:10 2003 +++ /usr/src/lib/libc/sys/madvise.2 Sat Jun 21 10:22:02 2003 @@ -36,7 +36,8 @@ .Dt MADVISE 2 .Os .Sh NAME -.Nm madvise +.Nm madvise , +.Nm posix_madvise .Nd give advice about use of memory .Sh LIBRARY .Lb libc @@ -44,6 +45,8 @@ .In sys/mman.h .Ft int .Fn madvise "void *addr" "size_t len" "int behav" +.Ft int +.Fn posix_madvise "void *addr" "size_t len" "int advice" .Sh DESCRIPTION The .Fn madvise @@ -51,6 +54,13 @@ allows a process that has knowledge of its memory behavior to describe it to the system. .Pp +The +.Fn posix_madvise +interface is identical and is provided for the purposes of +standards conformance. The +.Dv POSIX_ +prefixed definitions should be used when calling this interface. +.Pp The known behaviors are: .Bl -tag -width MADV_SEQUENTIAL .It Dv MADV_NORMAL @@ -123,7 +133,44 @@ The process must have superuser privileges. This should be used judiciously in processes that must remain running for the system to properly function. +.It Dv POSIX_MADV_NORMAL +Same as +.Dv MADV_NORMAL +but used with the +.Fn posix_madvise +system call. +.It Dv POSIX_MADV_SEQUENTIAL +Same as +.Dv MADV_SEQUENTIAL +but used with the +.Fn posix_madvise +system call. +.It Dv POSIX_MADV_RANDOM +Same as +.Dv MADV_RANDOM +but used with the +.Fn posix_madvise +system call. +.It Dv POSIX_MADV_WILLNEED +Same as +.Dv MADV_WILLNEED +but used with the +.Fn posix_madvise +system call. +.It Dv POSIX_MADV_WONTNEED +Same as +.Dv MADV_WONTNEED +but used with the +.Fn posix_madvise +system call. .El +.Sh IMPLEMENTATION NOTES +The +.Fn posix_madvise +function is implemented as a function within libc +which simply calls the +.Fn madvise +system call stub. .Sh RETURN VALUES .Rv -std madvise .Sh ERRORS @@ -146,6 +193,10 @@ .Xr mprotect 2 , .Xr msync 2 , .Xr munmap 2 +.Sh STANDARDS +The +.Fn posix_madvise +interface is believed to conform to IEEE Std 1003.1-2001 (``POSIX.1''). .Sh HISTORY The .Fn madvise --- posix_madvise.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: