summaryrefslogtreecommitdiffstats
path: root/man2/mremap.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/mremap.2')
-rw-r--r--man2/mremap.2352
1 files changed, 352 insertions, 0 deletions
diff --git a/man2/mremap.2 b/man2/mremap.2
new file mode 100644
index 0000000..f2b2b98
--- /dev/null
+++ b/man2/mremap.2
@@ -0,0 +1,352 @@
+.\" 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 2023-03-30 "Linux man-pages 6.05.01"
+.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>
+.PP
+.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).
+.PP
+\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.
+.PP
+If the value of \fIold_size\fP is zero, and \fIold_address\fP refers to
+a shareable mapping (see
+.BR mmap (2)
+.BR MAP_SHARED ),
+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.
+.PP
+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 .
+.PP
+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.
+.\" .PP
+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).
+.PP
+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.
+.PP
+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
+.RB ( mmap "(2) " MAP_PRIVATE ),
+.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)
+.PP
+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)