1MREMAP(2)                  Linux Programmer's Manual                 MREMAP(2)
2
3
4

NAME

6       mremap - remap a virtual memory address
7

SYNOPSIS

9       #define _GNU_SOURCE         /* See feature_test_macros(7) */
10       #include <sys/mman.h>
11
12       void *mremap(void *old_address, size_t old_size,
13                    size_t new_size, int flags, ... /* void *new_address */);
14

DESCRIPTION

16       mremap()  expands  (or shrinks) an existing memory mapping, potentially
17       moving it at the same time (controlled by the flags  argument  and  the
18       available virtual address space).
19
20       old_address  is  the  old  address of the virtual memory block that you
21       want to expand (or shrink).  Note  that  old_address  has  to  be  page
22       aligned.   old_size  is  the  old  size  of  the  virtual memory block.
23       new_size is the requested size of the virtual memory  block  after  the
24       resize.   An optional fifth argument, new_address, may be provided; see
25       the description of MREMAP_FIXED below.
26
27       If the value of old_size is zero, and old_address refers to a shareable
28       mapping  (see mmap(2) MAP_SHARED), then mremap() will create a new map‐
29       ping of the same pages.  new_size will be the size of the  new  mapping
30       and  the location of the new mapping may be specified with new_address;
31       see the description of MREMAP_FIXED below.  If a  new  mapping  is  re‐
32       quested  via  this  method,  then  the MREMAP_MAYMOVE flag must also be
33       specified.
34
35       The flags bit-mask argument may be 0, or include the following flags:
36
37       MREMAP_MAYMOVE
38              By default, if there is not sufficient space to expand a mapping
39              at  its  current location, then mremap() fails.  If this flag is
40              specified, then the kernel is permitted to relocate the  mapping
41              to a new virtual address, if necessary.  If the mapping is relo‐
42              cated, then absolute pointers into the old mapping location  be‐
43              come  invalid  (offsets  relative to the starting address of the
44              mapping should be employed).
45
46       MREMAP_FIXED (since Linux 2.3.31)
47              This flag serves a similar purpose  to  the  MAP_FIXED  flag  of
48              mmap(2).   If  this  flag  is specified, then mremap() accepts a
49              fifth  argument,  void *new_address,  which  specifies  a  page-
50              aligned  address to which the mapping must be moved.  Any previ‐
51              ous mapping at the address range specified  by  new_address  and
52              new_size is unmapped.
53
54              If  MREMAP_FIXED  is specified, then MREMAP_MAYMOVE must also be
55              specified.
56
57       MREMAP_DONTUNMAP (since Linux 5.7)
58              This flag, which must be used in  conjunction  with  MREMAP_MAY‐
59              MOVE,  remaps  a mapping to a new address but does not unmap the
60              mapping at old_address.
61
62              The MREMAP_DONTUNMAP flag can be used only with  private  anony‐
63              mous mappings (see the description of MAP_PRIVATE and MAP_ANONY‐
64              MOUS in mmap(2)).
65
66              After completion, any access to the range specified  by  old_ad‐
67              dress  and old_size will result in a page fault.  The page fault
68              will be handled by a userfaultfd(2) handler if the address is in
69              a  range  previously registered with userfaultfd(2).  Otherwise,
70              the kernel allocates a zero-filled page to handle the fault.
71
72              The MREMAP_DONTUNMAP flag may be used to atomically move a  map‐
73              ping while leaving the source mapped.  See NOTES for some possi‐
74              ble applications of MREMAP_DONTUNMAP.
75
76       If the memory segment specified by old_address and old_size  is  locked
77       (using mlock(2) or similar), then this lock is maintained when the seg‐
78       ment is resized and/or relocated.  As a consequence, the amount of mem‐
79       ory locked by the process may change.
80

RETURN VALUE

82       On  success  mremap() returns a pointer to the new virtual memory area.
83       On error, the value MAP_FAILED (that is, (void *) -1) is returned,  and
84       errno is set to indicate the error.
85

ERRORS

87       EAGAIN The  caller tried to expand a memory segment that is locked, but
88              this was not possible without exceeding the  RLIMIT_MEMLOCK  re‐
89              source limit.
90
91       EFAULT Some address in the range old_address to old_address+old_size is
92              an invalid virtual memory address for  this  process.   You  can
93              also  get  EFAULT  even  if  there exist mappings that cover the
94              whole address space requested, but those mappings are of differ‐
95              ent types.
96
97       EINVAL An invalid argument was given.  Possible causes are:
98
99              *  old_address was not page aligned;
100
101              *  a   value   other  than  MREMAP_MAYMOVE  or  MREMAP_FIXED  or
102                 MREMAP_DONTUNMAP was specified in flags;
103
104              *  new_size was zero;
105
106              *  new_size or new_address was invalid;
107
108              *  the new address range specified by new_address  and  new_size
109                 overlapped the old address range specified by old_address and
110                 old_size;
111
112              *  MREMAP_FIXED or MREMAP_DONTUNMAP was specified  without  also
113                 specifying MREMAP_MAYMOVE;
114
115              *  MREMAP_DONTUNMAP  was specified, but one or more pages in the
116                 range specified by old_address and old_size were not  private
117                 anonymous;
118
119              *  MREMAP_DONTUNMAP  was specified and old_size was not equal to
120                 new_size;
121
122              *  old_size was zero and old_address does not refer to a  share‐
123                 able mapping (but see BUGS);
124
125              *  old_size  was zero and the MREMAP_MAYMOVE flag was not speci‐
126                 fied.
127
128       ENOMEM Not enough memory was available to complete the operation.  Pos‐
129              sible causes are:
130
131              *  The memory area cannot be expanded at the current virtual ad‐
132                 dress, and the MREMAP_MAYMOVE flag is not set in flags.   Or,
133                 there is not enough (virtual) memory available.
134
135              *  MREMAP_DONTUNMAP was used causing a new mapping to be created
136                 that would exceed the (virtual)  memory  available.   Or,  it
137                 would exceed the maximum number of allowed mappings.
138

CONFORMING TO

140       This  call  is  Linux-specific,  and should not be used in programs in‐
141       tended to be portable.
142

NOTES

144       mremap() changes the  mapping  between  virtual  addresses  and  memory
145       pages.  This can be used to implement a very efficient realloc(3).
146
147       In Linux, memory is divided into pages.  A process has (one or) several
148       linear virtual memory segments.  Each virtual memory segment has one or
149       more  mappings  to real memory pages (in the page table).  Each virtual
150       memory segment has its own protection (access rights), which may  cause
151       a  segmentation  violation  (SIGSEGV)  if the memory is accessed incor‐
152       rectly (e.g., writing to a read-only segment).  Accessing virtual  mem‐
153       ory outside of the segments will also cause a segmentation violation.
154
155       If  mremap()  is used to move or expand an area locked with mlock(2) or
156       equivalent, the mremap() call will make a best effort to  populate  the
157       new area but will not fail with ENOMEM if the area cannot be populated.
158
159       Prior   to  version  2.4,  glibc  did  not  expose  the  definition  of
160       MREMAP_FIXED, and the prototype for mremap()  did  not  allow  for  the
161       new_address argument.
162
163   MREMAP_DONTUNMAP use cases
164       Possible applications for MREMAP_DONTUNMAP include:
165
166       *  Non-cooperative  userfaultfd(2):  an application can yank out a vir‐
167          tual address range using MREMAP_DONTUNMAP and then  employ  a  user‐
168          faultfd(2) handler to handle the page faults that subsequently occur
169          as other threads in the process touch pages in the yanked range.
170
171       *  Garbage collection: MREMAP_DONTUNMAP can be used in conjunction with
172          userfaultfd(2)  to implement garbage collection algorithms (e.g., in
173          a Java virtual machine).  Such an implementation can be cheaper (and
174          simpler)  than  conventional  garbage collection techniques that in‐
175          volve marking pages with protection PROT_NONE  in  conjunction  with
176          the of a SIGSEGV handler to catch accesses to those pages.
177

BUGS

179       Before  Linux 4.14, if old_size was zero and the mapping referred to by
180       old_address was a private mapping (mmap(2) MAP_PRIVATE), mremap()  cre‐
181       ated a new private mapping unrelated to the original mapping.  This be‐
182       havior was unintended and probably unexpected  in  user-space  applica‐
183       tions (since the intention of mremap() is to create a new mapping based
184       on the original mapping).  Since Linux 4.14, mremap()  fails  with  the
185       error EINVAL in this scenario.
186

SEE ALSO

188       brk(2),  getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2), mal‐
189       loc(3), realloc(3)
190
191       Your favorite text book on operating systems for  more  information  on
192       paged  memory  (e.g.,  Modern Operating Systems by Andrew S. Tanenbaum,
193       Inside Linux by Randolph Bentson, The Design of the UNIX Operating Sys‐
194       tem by Maurice J. Bach)
195

COLOPHON

197       This  page  is  part of release 5.12 of the Linux man-pages project.  A
198       description of the project, information about reporting bugs,  and  the
199       latest     version     of     this    page,    can    be    found    at
200       https://www.kernel.org/doc/man-pages/.
201
202
203
204Linux                             2021-03-22                         MREMAP(2)
Impressum