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)] 4 pub struct Advice(pub(crate) libc::c_int); 5 6 impl Advice { 7 /// **MADV_NORMAL** 8 /// 9 /// No special treatment. This is the default. normal() -> Self10 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.) random() -> Self18 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.) sequential() -> Self27 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.) will_need() -> Self35 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. dont_need() -> Self74 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"))] free() -> Self111 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")] remove() -> Self140 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")] dont_fork() -> Self153 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")] do_fork() -> Self162 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")] mergeable() -> Self187 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")] unmergeable() -> Self198 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")] huge_page() -> Self239 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")] no_huge_page() -> Self248 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")] dont_dump() -> Self262 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")] do_dump() -> Self270 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")] hw_poison() -> Self287 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")] populate_read() -> Self324 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")] populate_write() -> Self358 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"))] zero_wired_pages() -> Self369 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"))] free_reusable() -> Self383 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"))] free_reuse() -> Self399 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