diff options
Diffstat (limited to 'man/man2/mremap.2')
-rw-r--r-- | man/man2/mremap.2 | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/man/man2/mremap.2 b/man/man2/mremap.2 new file mode 100644 index 0000000..d25b234 --- /dev/null +++ b/man/man2/mremap.2 @@ -0,0 +1,357 @@ +.\" Copyright (c) 1996 Tom Bjorkholm <tomb@mydata.se> +.\" +.\" SPDX-License-Identifier: GPL-2.0-or-later +.\" +.\" 1996-04-11 Tom Bjorkholm <tomb@mydata.se> +.\" First version written (1.3.86) +.\" 1996-04-12 Tom Bjorkholm <tomb@mydata.se> +.\" Update for Linux 1.3.87 and later +.\" 2005-10-11 mtk: Added NOTES for MREMAP_FIXED; revised EINVAL text. +.\" +.TH mremap 2 2024-05-02 "Linux man-pages (unreleased)" +.SH NAME +mremap \- remap a virtual memory address +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #include <sys/mman.h> +.P +.BI "void *mremap(void " old_address [. old_size "], size_t " old_size , +.BI " size_t " new_size ", int " flags ", ... /* void *" new_address " */);" +.fi +.SH DESCRIPTION +.BR mremap () +expands (or shrinks) an existing memory mapping, potentially +moving it at the same time (controlled by the \fIflags\fP argument and +the available virtual address space). +.P +\fIold_address\fP is the old address of the virtual memory block that you +want to expand (or shrink). +Note that \fIold_address\fP has to be page +aligned. +\fIold_size\fP is the old size of the +virtual memory block. +\fInew_size\fP is the requested size of the +virtual memory block after the resize. +An optional fifth argument, +.IR new_address , +may be provided; see the description of +.B MREMAP_FIXED +below. +.P +If the value of \fIold_size\fP is zero, and \fIold_address\fP refers to +a shareable mapping +(see the description of +.B MAP_SHARED +in +.BR mmap (2)), +then +.BR mremap () +will create a new mapping of the same pages. +\fInew_size\fP +will be the size of the new mapping and the location of the new mapping +may be specified with \fInew_address\fP; see the description of +.B MREMAP_FIXED +below. +If a new mapping is requested via this method, then the +.B MREMAP_MAYMOVE +flag must also be specified. +.P +The \fIflags\fP bit-mask argument may be 0, or include the following flags: +.TP +.B MREMAP_MAYMOVE +By default, if there is not sufficient space to expand a mapping +at its current location, then +.BR mremap () +fails. +If this flag is specified, then the kernel is permitted to +relocate the mapping to a new virtual address, if necessary. +If the mapping is relocated, +then absolute pointers into the old mapping location +become invalid (offsets relative to the starting address of +the mapping should be employed). +.TP +.BR MREMAP_FIXED " (since Linux 2.3.31)" +This flag serves a similar purpose to the +.B MAP_FIXED +flag of +.BR mmap (2). +If this flag is specified, then +.BR mremap () +accepts a fifth argument, +.IR "void\ *new_address" , +which specifies a page-aligned address to which the mapping must +be moved. +Any previous mapping at the address range specified by +.I new_address +and +.I new_size +is unmapped. +.IP +If +.B MREMAP_FIXED +is specified, then +.B MREMAP_MAYMOVE +must also be specified. +.TP +.BR MREMAP_DONTUNMAP " (since Linux 5.7)" +.\" commit e346b3813067d4b17383f975f197a9aa28a3b077 +This flag, which must be used in conjunction with +.BR MREMAP_MAYMOVE , +remaps a mapping to a new address but does not unmap the mapping at +.IR old_address . +.IP +The +.B MREMAP_DONTUNMAP +flag can be used only with private anonymous mappings +(see the description of +.B MAP_PRIVATE +and +.B MAP_ANONYMOUS +in +.BR mmap (2)). +.IP +After completion, +any access to the range specified by +.I old_address +and +.I old_size +will result in a page fault. +The page fault will be handled by a +.BR userfaultfd (2) +handler +if the address is in a range previously registered with +.BR userfaultfd (2). +Otherwise, the kernel allocates a zero-filled page to handle the fault. +.IP +The +.B MREMAP_DONTUNMAP +flag may be used to atomically move a mapping while leaving the source +mapped. +See NOTES for some possible applications of +.BR MREMAP_DONTUNMAP . +.P +If the memory segment specified by +.I old_address +and +.I old_size +is locked (using +.BR mlock (2) +or similar), then this lock is maintained when the segment is +resized and/or relocated. +As a consequence, the amount of memory locked by the process may change. +.SH RETURN VALUE +On success +.BR mremap () +returns a pointer to the new virtual memory area. +On error, the value +.B MAP_FAILED +(that is, \fI(void\ *)\ \-1\fP) is returned, +and \fIerrno\fP is set to indicate the error. +.SH ERRORS +.TP +.B EAGAIN +The caller tried to expand a memory segment that is locked, +but this was not possible without exceeding the +.B RLIMIT_MEMLOCK +resource limit. +.TP +.B EFAULT +Some address in the range +\fIold_address\fP to \fIold_address\fP+\fIold_size\fP is an invalid +virtual memory address for this process. +You can also get +.B EFAULT +even if there exist mappings that cover the +whole address space requested, but those mappings are of different types. +.TP +.B EINVAL +An invalid argument was given. +Possible causes are: +.RS +.IP \[bu] 3 +\fIold_address\fP was not +page aligned; +.IP \[bu] +a value other than +.B MREMAP_MAYMOVE +or +.B MREMAP_FIXED +or +.B MREMAP_DONTUNMAP +was specified in +.IR flags ; +.IP \[bu] +.I new_size +was zero; +.IP \[bu] +.I new_size +or +.I new_address +was invalid; +.IP \[bu] +the new address range specified by +.I new_address +and +.I new_size +overlapped the old address range specified by +.I old_address +and +.IR old_size ; +.IP \[bu] +.B MREMAP_FIXED +or +.B MREMAP_DONTUNMAP +was specified without also specifying +.BR MREMAP_MAYMOVE ; +.IP \[bu] +.B MREMAP_DONTUNMAP +was specified, but one or more pages in the range specified by +.I old_address +and +.I old_size +were not private anonymous; +.IP \[bu] +.B MREMAP_DONTUNMAP +was specified and +.I old_size +was not equal to +.IR new_size ; +.IP \[bu] +\fIold_size\fP was zero and \fIold_address\fP does not refer to a +shareable mapping (but see BUGS); +.IP \[bu] +\fIold_size\fP was zero and the +.B MREMAP_MAYMOVE +flag was not specified. +.RE +.TP +.B ENOMEM +Not enough memory was available to complete the operation. +Possible causes are: +.RS +.IP \[bu] 3 +The memory area cannot be expanded at the current virtual address, and the +.B MREMAP_MAYMOVE +flag is not set in \fIflags\fP. +Or, there is not enough (virtual) memory available. +.IP \[bu] +.B MREMAP_DONTUNMAP +was used causing a new mapping to be created that would exceed the +(virtual) memory available. +Or, it would exceed the maximum number of allowed mappings. +.RE +.SH STANDARDS +Linux. +.SH HISTORY +.\" 4.2BSD had a (never actually implemented) +.\" .BR mremap (2) +.\" call with completely different semantics. +.\" .P +Prior to glibc 2.4, glibc did not expose the definition of +.BR MREMAP_FIXED , +and the prototype for +.BR mremap () +did not allow for the +.I new_address +argument. +.SH NOTES +.BR mremap () +changes the +mapping between virtual addresses and memory pages. +This can be used to implement a very efficient +.BR realloc (3). +.P +In Linux, memory is divided into pages. +A process has (one or) +several linear virtual memory segments. +Each virtual memory segment has one +or more mappings to real memory pages (in the page table). +Each virtual memory segment has its own +protection (access rights), which may cause +a segmentation violation +.RB ( SIGSEGV ) +if the memory is accessed incorrectly (e.g., +writing to a read-only segment). +Accessing virtual memory outside of the +segments will also cause a segmentation violation. +.P +If +.BR mremap () +is used to move or expand an area locked with +.BR mlock (2) +or equivalent, the +.BR mremap () +call will make a best effort to populate the new area but will not fail +with +.B ENOMEM +if the area cannot be populated. +.\" +.SS MREMAP_DONTUNMAP use cases +Possible applications for +.B MREMAP_DONTUNMAP +include: +.IP \[bu] 3 +Non-cooperative +.BR userfaultfd (2): +an application can yank out a virtual address range using +.B MREMAP_DONTUNMAP +and then employ a +.BR userfaultfd (2) +handler to handle the page faults that subsequently occur +as other threads in the process touch pages in the yanked range. +.IP \[bu] +Garbage collection: +.B MREMAP_DONTUNMAP +can be used in conjunction with +.BR userfaultfd (2) +to implement garbage collection algorithms (e.g., in a Java virtual machine). +Such an implementation can be cheaper (and simpler) +than conventional garbage collection techniques that involve +marking pages with protection +.B PROT_NONE +in conjunction with the use of a +.B SIGSEGV +handler to catch accesses to those pages. +.SH BUGS +Before Linux 4.14, +if +.I old_size +was zero and the mapping referred to by +.I old_address +was a private mapping +(see the description of +.B MAP_PRIVATE +in +.BR mmap (2)), +.BR mremap () +created a new private mapping unrelated to the original mapping. +This behavior was unintended +and probably unexpected in user-space applications +(since the intention of +.BR mremap () +is to create a new mapping based on the original mapping). +Since Linux 4.14, +.\" commit dba58d3b8c5045ad89c1c95d33d01451e3964db7 +.BR mremap () +fails with the error +.B EINVAL +in this scenario. +.SH SEE ALSO +.BR brk (2), +.BR getpagesize (2), +.BR getrlimit (2), +.BR mlock (2), +.BR mmap (2), +.BR sbrk (2), +.BR malloc (3), +.BR realloc (3) +.P +Your favorite text book on operating systems +for more information on paged memory +(e.g., \fIModern Operating Systems\fP by Andrew S.\& Tanenbaum, +\fIInside Linux\fP by Randolph Bentson, +\fIThe Design of the UNIX Operating System\fP by Maurice J.\& Bach) |