1 | /// Values supported by [`Mmap::advise`][crate::Mmap::advise] and [`MmapMut::advise`][crate::MmapMut::advise] functions. |
2 | /// |
3 | /// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. |
4 | #[repr (i32)] |
5 | #[derive (Clone, Copy, Debug, Eq, PartialEq, Hash)] |
6 | pub enum Advice { |
7 | /// **MADV_NORMAL** |
8 | /// |
9 | /// No special treatment. This is the default. |
10 | Normal = libc::MADV_NORMAL, |
11 | |
12 | /// **MADV_RANDOM** |
13 | /// |
14 | /// Expect page references in random order. (Hence, read |
15 | /// ahead may be less useful than normally.) |
16 | Random = libc::MADV_RANDOM, |
17 | |
18 | /// **MADV_SEQUENTIAL** |
19 | /// |
20 | /// Expect page references in sequential order. (Hence, pages |
21 | /// in the given range can be aggressively read ahead, and may |
22 | /// be freed soon after they are accessed.) |
23 | Sequential = libc::MADV_SEQUENTIAL, |
24 | |
25 | /// **MADV_WILLNEED** |
26 | /// |
27 | /// Expect access in the near future. (Hence, it might be a |
28 | /// good idea to read some pages ahead.) |
29 | WillNeed = libc::MADV_WILLNEED, |
30 | |
31 | /// **MADV_DONTFORK** - Linux only (since Linux 2.6.16) |
32 | /// |
33 | /// Do not make the pages in this range available to the child |
34 | /// after a fork(2). This is useful to prevent copy-on-write |
35 | /// semantics from changing the physical location of a page if |
36 | /// the parent writes to it after a fork(2). (Such page |
37 | /// relocations cause problems for hardware that DMAs into the |
38 | /// page.) |
39 | #[cfg (target_os = "linux" )] |
40 | DontFork = libc::MADV_DONTFORK, |
41 | |
42 | /// **MADV_DOFORK** - Linux only (since Linux 2.6.16) |
43 | /// |
44 | /// Undo the effect of MADV_DONTFORK, restoring the default |
45 | /// behavior, whereby a mapping is inherited across fork(2). |
46 | #[cfg (target_os = "linux" )] |
47 | DoFork = libc::MADV_DOFORK, |
48 | |
49 | /// **MADV_MERGEABLE** - Linux only (since Linux 2.6.32) |
50 | /// |
51 | /// Enable Kernel Samepage Merging (KSM) for the pages in the |
52 | /// range specified by addr and length. The kernel regularly |
53 | /// scans those areas of user memory that have been marked as |
54 | /// mergeable, looking for pages with identical content. |
55 | /// These are replaced by a single write-protected page (which |
56 | /// is automatically copied if a process later wants to update |
57 | /// the content of the page). KSM merges only private |
58 | /// anonymous pages (see mmap(2)). |
59 | /// |
60 | /// The KSM feature is intended for applications that generate |
61 | /// many instances of the same data (e.g., virtualization |
62 | /// systems such as KVM). It can consume a lot of processing |
63 | /// power; use with care. See the Linux kernel source file |
64 | /// Documentation/admin-guide/mm/ksm.rst for more details. |
65 | /// |
66 | /// The MADV_MERGEABLE and MADV_UNMERGEABLE operations are |
67 | /// available only if the kernel was configured with |
68 | /// CONFIG_KSM. |
69 | #[cfg (target_os = "linux" )] |
70 | Mergeable = libc::MADV_MERGEABLE, |
71 | |
72 | /// **MADV_UNMERGEABLE** - Linux only (since Linux 2.6.32) |
73 | /// |
74 | /// Undo the effect of an earlier MADV_MERGEABLE operation on |
75 | /// the specified address range; KSM unmerges whatever pages |
76 | /// it had merged in the address range specified by addr and |
77 | /// length. |
78 | #[cfg (target_os = "linux" )] |
79 | Unmergeable = libc::MADV_UNMERGEABLE, |
80 | |
81 | /// **MADV_HUGEPAGE** - Linux only (since Linux 2.6.38) |
82 | /// |
83 | /// Enable Transparent Huge Pages (THP) for pages in the range |
84 | /// specified by addr and length. Currently, Transparent Huge |
85 | /// Pages work only with private anonymous pages (see |
86 | /// mmap(2)). The kernel will regularly scan the areas marked |
87 | /// as huge page candidates to replace them with huge pages. |
88 | /// The kernel will also allocate huge pages directly when the |
89 | /// region is naturally aligned to the huge page size (see |
90 | /// posix_memalign(2)). |
91 | /// |
92 | /// This feature is primarily aimed at applications that use |
93 | /// large mappings of data and access large regions of that |
94 | /// memory at a time (e.g., virtualization systems such as |
95 | /// QEMU). It can very easily waste memory (e.g., a 2 MB |
96 | /// mapping that only ever accesses 1 byte will result in 2 MB |
97 | /// of wired memory instead of one 4 KB page). See the Linux |
98 | /// kernel source file |
99 | /// Documentation/admin-guide/mm/transhuge.rst for more |
100 | /// details. |
101 | /// |
102 | /// Most common kernels configurations provide MADV_HUGEPAGE- |
103 | /// style behavior by default, and thus MADV_HUGEPAGE is |
104 | /// normally not necessary. It is mostly intended for |
105 | /// embedded systems, where MADV_HUGEPAGE-style behavior may |
106 | /// not be enabled by default in the kernel. On such systems, |
107 | /// this flag can be used in order to selectively enable THP. |
108 | /// Whenever MADV_HUGEPAGE is used, it should always be in |
109 | /// regions of memory with an access pattern that the |
110 | /// developer knows in advance won't risk to increase the |
111 | /// memory footprint of the application when transparent |
112 | /// hugepages are enabled. |
113 | /// |
114 | /// The MADV_HUGEPAGE and MADV_NOHUGEPAGE operations are |
115 | /// available only if the kernel was configured with |
116 | /// CONFIG_TRANSPARENT_HUGEPAGE. |
117 | #[cfg (target_os = "linux" )] |
118 | HugePage = libc::MADV_HUGEPAGE, |
119 | |
120 | /// **MADV_NOHUGEPAGE** - Linux only (since Linux 2.6.38) |
121 | /// |
122 | /// Ensures that memory in the address range specified by addr |
123 | /// and length will not be backed by transparent hugepages. |
124 | #[cfg (target_os = "linux" )] |
125 | NoHugePage = libc::MADV_NOHUGEPAGE, |
126 | |
127 | /// **MADV_DONTDUMP** - Linux only (since Linux 3.4) |
128 | /// |
129 | /// Exclude from a core dump those pages in the range |
130 | /// specified by addr and length. This is useful in |
131 | /// applications that have large areas of memory that are |
132 | /// known not to be useful in a core dump. The effect of |
133 | /// **MADV_DONTDUMP** takes precedence over the bit mask that is |
134 | /// set via the `/proc/[pid]/coredump_filter` file (see |
135 | /// core(5)). |
136 | #[cfg (target_os = "linux" )] |
137 | DontDump = libc::MADV_DONTDUMP, |
138 | |
139 | /// **MADV_DODUMP** - Linux only (since Linux 3.4) |
140 | /// |
141 | /// Undo the effect of an earlier MADV_DONTDUMP. |
142 | #[cfg (target_os = "linux" )] |
143 | DoDump = libc::MADV_DODUMP, |
144 | |
145 | /// **MADV_HWPOISON** - Linux only (since Linux 2.6.32) |
146 | /// |
147 | /// Poison the pages in the range specified by addr and length |
148 | /// and handle subsequent references to those pages like a |
149 | /// hardware memory corruption. This operation is available |
150 | /// only for privileged (CAP_SYS_ADMIN) processes. This |
151 | /// operation may result in the calling process receiving a |
152 | /// SIGBUS and the page being unmapped. |
153 | /// |
154 | /// This feature is intended for testing of memory error- |
155 | /// handling code; it is available only if the kernel was |
156 | /// configured with CONFIG_MEMORY_FAILURE. |
157 | #[cfg (target_os = "linux" )] |
158 | HwPoison = libc::MADV_HWPOISON, |
159 | |
160 | /// **MADV_POPULATE_READ** - Linux only (since Linux 5.14) |
161 | /// |
162 | /// Populate (prefault) page tables readable, faulting in all |
163 | /// pages in the range just as if manually reading from each |
164 | /// page; however, avoid the actual memory access that would have |
165 | /// been performed after handling the fault. |
166 | /// |
167 | /// In contrast to MAP_POPULATE, MADV_POPULATE_READ does not hide |
168 | /// errors, can be applied to (parts of) existing mappings and |
169 | /// will always populate (prefault) page tables readable. One |
170 | /// example use case is prefaulting a file mapping, reading all |
171 | /// file content from disk; however, pages won't be dirtied and |
172 | /// consequently won't have to be written back to disk when |
173 | /// evicting the pages from memory. |
174 | /// |
175 | /// Depending on the underlying mapping, map the shared zeropage, |
176 | /// preallocate memory or read the underlying file; files with |
177 | /// holes might or might not preallocate blocks. If populating |
178 | /// fails, a SIGBUS signal is not generated; instead, an error is |
179 | /// returned. |
180 | /// |
181 | /// If MADV_POPULATE_READ succeeds, all page tables have been |
182 | /// populated (prefaulted) readable once. If MADV_POPULATE_READ |
183 | /// fails, some page tables might have been populated. |
184 | /// |
185 | /// MADV_POPULATE_READ cannot be applied to mappings without read |
186 | /// permissions and special mappings, for example, mappings |
187 | /// marked with kernel-internal flags such as VM_PFNMAP or VM_IO, |
188 | /// or secret memory regions created using memfd_secret(2). |
189 | /// |
190 | /// Note that with MADV_POPULATE_READ, the process can be killed |
191 | /// at any moment when the system runs out of memory. |
192 | #[cfg (target_os = "linux" )] |
193 | PopulateRead = libc::MADV_POPULATE_READ, |
194 | |
195 | /// **MADV_POPULATE_WRITE** - Linux only (since Linux 5.14) |
196 | /// |
197 | /// Populate (prefault) page tables writable, faulting in all |
198 | /// pages in the range just as if manually writing to each each |
199 | /// page; however, avoid the actual memory access that would have |
200 | /// been performed after handling the fault. |
201 | /// |
202 | /// In contrast to MAP_POPULATE, MADV_POPULATE_WRITE does not |
203 | /// hide errors, can be applied to (parts of) existing mappings |
204 | /// and will always populate (prefault) page tables writable. |
205 | /// One example use case is preallocating memory, breaking any |
206 | /// CoW (Copy on Write). |
207 | /// |
208 | /// Depending on the underlying mapping, preallocate memory or |
209 | /// read the underlying file; files with holes will preallocate |
210 | /// blocks. If populating fails, a SIGBUS signal is not gener‐ |
211 | /// ated; instead, an error is returned. |
212 | /// |
213 | /// If MADV_POPULATE_WRITE succeeds, all page tables have been |
214 | /// populated (prefaulted) writable once. If MADV_POPULATE_WRITE |
215 | /// fails, some page tables might have been populated. |
216 | /// |
217 | /// MADV_POPULATE_WRITE cannot be applied to mappings without |
218 | /// write permissions and special mappings, for example, mappings |
219 | /// marked with kernel-internal flags such as VM_PFNMAP or VM_IO, |
220 | /// or secret memory regions created using memfd_secret(2). |
221 | /// |
222 | /// Note that with MADV_POPULATE_WRITE, the process can be killed |
223 | /// at any moment when the system runs out of memory. |
224 | #[cfg (target_os = "linux" )] |
225 | PopulateWrite = libc::MADV_POPULATE_WRITE, |
226 | |
227 | /// **MADV_ZERO_WIRED_PAGES** - Darwin only |
228 | /// |
229 | /// Indicates that the application would like the wired pages in this address range to be |
230 | /// zeroed out if the address range is deallocated without first unwiring the pages (i.e. |
231 | /// a munmap(2) without a preceding munlock(2) or the application quits). This is used |
232 | /// with madvise() system call. |
233 | #[cfg (any(target_os = "macos" , target_os = "ios" ))] |
234 | ZeroWiredPages = libc::MADV_ZERO_WIRED_PAGES, |
235 | } |
236 | |
237 | /// Values supported by [`Mmap::unsafe_advise`][crate::Mmap::unsafe_advise] and [`MmapMut::unsafe_advise`][crate::MmapMut::unsafe_advise] functions. |
238 | /// |
239 | /// These flags can be passed to the [madvise (2)][man_page] system call |
240 | /// and effects on the mapped pages which are conceptually writes, |
241 | /// i.e. the change the observable contents of these pages which |
242 | /// implies undefined behaviour if the mapping is still borrowed. |
243 | /// |
244 | /// Hence, these potentially unsafe flags must be used with the unsafe |
245 | /// methods and the programmer has to justify that the code |
246 | /// does not keep any borrows of the mapping active while the mapped pages |
247 | /// are updated by the kernel's memory management subsystem. |
248 | /// |
249 | /// [man_page]: https://man7.org/linux/man-pages/man2/madvise.2.html |
250 | #[repr (i32)] |
251 | #[derive (Clone, Copy, Debug, Eq, PartialEq, Hash)] |
252 | pub enum UncheckedAdvice { |
253 | /// **MADV_DONTNEED** |
254 | /// |
255 | /// Do not expect access in the near future. (For the time |
256 | /// being, the application is finished with the given range, |
257 | /// so the kernel can free resources associated with it.) |
258 | /// |
259 | /// After a successful MADV_DONTNEED operation, the semantics |
260 | /// of memory access in the specified region are changed: |
261 | /// subsequent accesses of pages in the range will succeed, |
262 | /// but will result in either repopulating the memory contents |
263 | /// from the up-to-date contents of the underlying mapped file |
264 | /// (for shared file mappings, shared anonymous mappings, and |
265 | /// shmem-based techniques such as System V shared memory |
266 | /// segments) or zero-fill-on-demand pages for anonymous |
267 | /// private mappings. |
268 | /// |
269 | /// Note that, when applied to shared mappings, MADV_DONTNEED |
270 | /// might not lead to immediate freeing of the pages in the |
271 | /// range. The kernel is free to delay freeing the pages |
272 | /// until an appropriate moment. The resident set size (RSS) |
273 | /// of the calling process will be immediately reduced |
274 | /// however. |
275 | /// |
276 | /// **MADV_DONTNEED** cannot be applied to locked pages, Huge TLB |
277 | /// pages, or VM_PFNMAP pages. (Pages marked with the kernel- |
278 | /// internal VM_PFNMAP flag are special memory areas that are |
279 | /// not managed by the virtual memory subsystem. Such pages |
280 | /// are typically created by device drivers that map the pages |
281 | /// into user space.) |
282 | /// |
283 | /// # Safety |
284 | /// |
285 | /// Using the returned value with conceptually write to the |
286 | /// mapped pages, i.e. borrowing the mapping when the pages |
287 | /// are freed results in undefined behaviour. |
288 | DontNeed = libc::MADV_DONTNEED, |
289 | |
290 | // |
291 | // The rest are Linux-specific |
292 | // |
293 | /// **MADV_FREE** - Linux (since Linux 4.5) and Darwin |
294 | /// |
295 | /// The application no longer requires the pages in the range |
296 | /// specified by addr and len. The kernel can thus free these |
297 | /// pages, but the freeing could be delayed until memory |
298 | /// pressure occurs. For each of the pages that has been |
299 | /// marked to be freed but has not yet been freed, the free |
300 | /// operation will be canceled if the caller writes into the |
301 | /// page. After a successful MADV_FREE operation, any stale |
302 | /// data (i.e., dirty, unwritten pages) will be lost when the |
303 | /// kernel frees the pages. However, subsequent writes to |
304 | /// pages in the range will succeed and then kernel cannot |
305 | /// free those dirtied pages, so that the caller can always |
306 | /// see just written data. If there is no subsequent write, |
307 | /// the kernel can free the pages at any time. Once pages in |
308 | /// the range have been freed, the caller will see zero-fill- |
309 | /// on-demand pages upon subsequent page references. |
310 | /// |
311 | /// The MADV_FREE operation can be applied only to private |
312 | /// anonymous pages (see mmap(2)). In Linux before version |
313 | /// 4.12, when freeing pages on a swapless system, the pages |
314 | /// in the given range are freed instantly, regardless of |
315 | /// memory pressure. |
316 | /// |
317 | /// # Safety |
318 | /// |
319 | /// Using the returned value with conceptually write to the |
320 | /// mapped pages, i.e. borrowing the mapping while the pages |
321 | /// are still being freed results in undefined behaviour. |
322 | #[cfg (any(target_os = "linux" , target_os = "macos" , target_os = "ios" ))] |
323 | Free = libc::MADV_FREE, |
324 | |
325 | /// **MADV_REMOVE** - Linux only (since Linux 2.6.16) |
326 | /// |
327 | /// Free up a given range of pages and its associated backing |
328 | /// store. This is equivalent to punching a hole in the |
329 | /// corresponding byte range of the backing store (see |
330 | /// fallocate(2)). Subsequent accesses in the specified |
331 | /// address range will see bytes containing zero. |
332 | /// |
333 | /// The specified address range must be mapped shared and |
334 | /// writable. This flag cannot be applied to locked pages, |
335 | /// Huge TLB pages, or VM_PFNMAP pages. |
336 | /// |
337 | /// In the initial implementation, only tmpfs(5) was supported |
338 | /// **MADV_REMOVE**; but since Linux 3.5, any filesystem which |
339 | /// supports the fallocate(2) FALLOC_FL_PUNCH_HOLE mode also |
340 | /// supports MADV_REMOVE. Hugetlbfs fails with the error |
341 | /// EINVAL and other filesystems fail with the error |
342 | /// EOPNOTSUPP. |
343 | /// |
344 | /// # Safety |
345 | /// |
346 | /// Using the returned value with conceptually write to the |
347 | /// mapped pages, i.e. borrowing the mapping when the pages |
348 | /// are freed results in undefined behaviour. |
349 | #[cfg (target_os = "linux" )] |
350 | Remove = libc::MADV_REMOVE, |
351 | |
352 | /// **MADV_FREE_REUSABLE** - Darwin only |
353 | /// |
354 | /// Behaves like **MADV_FREE**, but the freed pages are accounted for in the RSS of the process. |
355 | /// |
356 | /// # Safety |
357 | /// |
358 | /// Using the returned value with conceptually write to the |
359 | /// mapped pages, i.e. borrowing the mapping while the pages |
360 | /// are still being freed results in undefined behaviour. |
361 | #[cfg (any(target_os = "macos" , target_os = "ios" ))] |
362 | FreeReusable = libc::MADV_FREE_REUSABLE, |
363 | |
364 | /// **MADV_FREE_REUSE** - Darwin only |
365 | /// |
366 | /// Marks a memory region previously freed by **MADV_FREE_REUSABLE** as non-reusable, accounts |
367 | /// for the pages in the RSS of the process. Pages that have been freed will be replaced by |
368 | /// zero-filled pages on demand, other pages will be left as is. |
369 | /// |
370 | /// # Safety |
371 | /// |
372 | /// Using the returned value with conceptually write to the |
373 | /// mapped pages, i.e. borrowing the mapping while the pages |
374 | /// are still being freed results in undefined behaviour. |
375 | #[cfg (any(target_os = "macos" , target_os = "ios" ))] |
376 | FreeReuse = libc::MADV_FREE_REUSE, |
377 | } |
378 | |
379 | // Future expansion: |
380 | // MADV_SOFT_OFFLINE (since Linux 2.6.33) |
381 | // MADV_WIPEONFORK (since Linux 4.14) |
382 | // MADV_KEEPONFORK (since Linux 4.14) |
383 | // MADV_COLD (since Linux 5.4) |
384 | // MADV_PAGEOUT (since Linux 5.4) |
385 | |