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