1mremap(2)                     System Calls Manual                    mremap(2)
2
3
4

NAME

6       mremap - remap a virtual memory address
7

LIBRARY

9       Standard C library (libc, -lc)
10

SYNOPSIS

12       #define _GNU_SOURCE         /* See feature_test_macros(7) */
13       #include <sys/mman.h>
14
15       void *mremap(void old_address[.old_size], size_t old_size,
16                    size_t new_size, int flags, ... /* void *new_address */);
17

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

STANDARDS

143       Linux.
144

HISTORY

146       Prior   to   glibc   2.4,  glibc  did  not  expose  the  definition  of
147       MREMAP_FIXED, and the prototype for mremap()  did  not  allow  for  the
148       new_address argument.
149

NOTES

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

BUGS

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

SEE ALSO

191       brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2),  mal‐
192       loc(3), realloc(3)
193
194       Your  favorite  text  book on operating systems for more information on
195       paged memory (e.g., Modern Operating Systems by  Andrew  S.  Tanenbaum,
196       Inside Linux by Randolph Bentson, The Design of the UNIX Operating Sys‐
197       tem by Maurice J. Bach)
198
199
200
201Linux man-pages 6.05              2023-03-30                         mremap(2)
Impressum