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
32       requested  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
43              become  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
67              old_address  and old_size will result in a page fault.  The page
68              fault will be handled by a userfaultfd(2) handler if the address
69              is in a range previously registered with userfaultfd(2).  Other‐
70              wise, the kernel allocates a  zero-filled  page  to  handle  the
71              fault.
72
73              The  MREMAP_DONTUNMAP flag may be used to atomically move a map‐
74              ping while leaving the source mapped.  See NOTES for some possi‐
75              ble applications of MREMAP_DONTUNMAP.
76
77       If  the  memory segment specified by old_address and old_size is locked
78       (using mlock(2) or similar), then this lock is maintained when the seg‐
79       ment is resized and/or relocated.  As a consequence, the amount of mem‐
80       ory locked by the process may change.
81

RETURN VALUE

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

ERRORS

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

CONFORMING TO

141       This call is  Linux-specific,  and  should  not  be  used  in  programs
142       intended to be portable.
143

NOTES

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

BUGS

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

SEE ALSO

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

COLOPHON

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