diff options
Diffstat (limited to 'third_party/rust/memmap2/src/advice.rs')
-rw-r--r-- | third_party/rust/memmap2/src/advice.rs | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/third_party/rust/memmap2/src/advice.rs b/third_party/rust/memmap2/src/advice.rs new file mode 100644 index 0000000000..4316058fc8 --- /dev/null +++ b/third_party/rust/memmap2/src/advice.rs @@ -0,0 +1,384 @@ +/// Values supported by [`Mmap::advise`][crate::Mmap::advise] and [`MmapMut::advise`][crate::MmapMut::advise] functions. +/// +/// See [madvise()](https://man7.org/linux/man-pages/man2/madvise.2.html) map page. +#[repr(i32)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum Advice { + /// **MADV_NORMAL** + /// + /// No special treatment. This is the default. + Normal = libc::MADV_NORMAL, + + /// **MADV_RANDOM** + /// + /// Expect page references in random order. (Hence, read + /// ahead may be less useful than normally.) + Random = libc::MADV_RANDOM, + + /// **MADV_SEQUENTIAL** + /// + /// Expect page references in sequential order. (Hence, pages + /// in the given range can be aggressively read ahead, and may + /// be freed soon after they are accessed.) + Sequential = libc::MADV_SEQUENTIAL, + + /// **MADV_WILLNEED** + /// + /// Expect access in the near future. (Hence, it might be a + /// good idea to read some pages ahead.) + WillNeed = libc::MADV_WILLNEED, + + /// **MADV_DONTFORK** - Linux only (since Linux 2.6.16) + /// + /// Do not make the pages in this range available to the child + /// after a fork(2). This is useful to prevent copy-on-write + /// semantics from changing the physical location of a page if + /// the parent writes to it after a fork(2). (Such page + /// relocations cause problems for hardware that DMAs into the + /// page.) + #[cfg(target_os = "linux")] + DontFork = libc::MADV_DONTFORK, + + /// **MADV_DOFORK** - Linux only (since Linux 2.6.16) + /// + /// Undo the effect of MADV_DONTFORK, restoring the default + /// behavior, whereby a mapping is inherited across fork(2). + #[cfg(target_os = "linux")] + DoFork = libc::MADV_DOFORK, + + /// **MADV_MERGEABLE** - Linux only (since Linux 2.6.32) + /// + /// Enable Kernel Samepage Merging (KSM) for the pages in the + /// range specified by addr and length. The kernel regularly + /// scans those areas of user memory that have been marked as + /// mergeable, looking for pages with identical content. + /// These are replaced by a single write-protected page (which + /// is automatically copied if a process later wants to update + /// the content of the page). KSM merges only private + /// anonymous pages (see mmap(2)). + /// + /// The KSM feature is intended for applications that generate + /// many instances of the same data (e.g., virtualization + /// systems such as KVM). It can consume a lot of processing + /// power; use with care. See the Linux kernel source file + /// Documentation/admin-guide/mm/ksm.rst for more details. + /// + /// The MADV_MERGEABLE and MADV_UNMERGEABLE operations are + /// available only if the kernel was configured with + /// CONFIG_KSM. + #[cfg(target_os = "linux")] + Mergeable = libc::MADV_MERGEABLE, + + /// **MADV_UNMERGEABLE** - Linux only (since Linux 2.6.32) + /// + /// Undo the effect of an earlier MADV_MERGEABLE operation on + /// the specified address range; KSM unmerges whatever pages + /// it had merged in the address range specified by addr and + /// length. + #[cfg(target_os = "linux")] + Unmergeable = libc::MADV_UNMERGEABLE, + + /// **MADV_HUGEPAGE** - Linux only (since Linux 2.6.38) + /// + /// Enable Transparent Huge Pages (THP) for pages in the range + /// specified by addr and length. Currently, Transparent Huge + /// Pages work only with private anonymous pages (see + /// mmap(2)). The kernel will regularly scan the areas marked + /// as huge page candidates to replace them with huge pages. + /// The kernel will also allocate huge pages directly when the + /// region is naturally aligned to the huge page size (see + /// posix_memalign(2)). + /// + /// This feature is primarily aimed at applications that use + /// large mappings of data and access large regions of that + /// memory at a time (e.g., virtualization systems such as + /// QEMU). It can very easily waste memory (e.g., a 2 MB + /// mapping that only ever accesses 1 byte will result in 2 MB + /// of wired memory instead of one 4 KB page). See the Linux + /// kernel source file + /// Documentation/admin-guide/mm/transhuge.rst for more + /// details. + /// + /// Most common kernels configurations provide MADV_HUGEPAGE- + /// style behavior by default, and thus MADV_HUGEPAGE is + /// normally not necessary. It is mostly intended for + /// embedded systems, where MADV_HUGEPAGE-style behavior may + /// not be enabled by default in the kernel. On such systems, + /// this flag can be used in order to selectively enable THP. + /// Whenever MADV_HUGEPAGE is used, it should always be in + /// regions of memory with an access pattern that the + /// developer knows in advance won't risk to increase the + /// memory footprint of the application when transparent + /// hugepages are enabled. + /// + /// The MADV_HUGEPAGE and MADV_NOHUGEPAGE operations are + /// available only if the kernel was configured with + /// CONFIG_TRANSPARENT_HUGEPAGE. + #[cfg(target_os = "linux")] + HugePage = libc::MADV_HUGEPAGE, + + /// **MADV_NOHUGEPAGE** - Linux only (since Linux 2.6.38) + /// + /// Ensures that memory in the address range specified by addr + /// and length will not be backed by transparent hugepages. + #[cfg(target_os = "linux")] + NoHugePage = libc::MADV_NOHUGEPAGE, + + /// **MADV_DONTDUMP** - Linux only (since Linux 3.4) + /// + /// Exclude from a core dump those pages in the range + /// specified by addr and length. This is useful in + /// applications that have large areas of memory that are + /// known not to be useful in a core dump. The effect of + /// **MADV_DONTDUMP** takes precedence over the bit mask that is + /// set via the `/proc/[pid]/coredump_filter` file (see + /// core(5)). + #[cfg(target_os = "linux")] + DontDump = libc::MADV_DONTDUMP, + + /// **MADV_DODUMP** - Linux only (since Linux 3.4) + /// + /// Undo the effect of an earlier MADV_DONTDUMP. + #[cfg(target_os = "linux")] + DoDump = libc::MADV_DODUMP, + + /// **MADV_HWPOISON** - Linux only (since Linux 2.6.32) + /// + /// Poison the pages in the range specified by addr and length + /// and handle subsequent references to those pages like a + /// hardware memory corruption. This operation is available + /// only for privileged (CAP_SYS_ADMIN) processes. This + /// operation may result in the calling process receiving a + /// SIGBUS and the page being unmapped. + /// + /// This feature is intended for testing of memory error- + /// handling code; it is available only if the kernel was + /// configured with CONFIG_MEMORY_FAILURE. + #[cfg(target_os = "linux")] + HwPoison = libc::MADV_HWPOISON, + + /// **MADV_POPULATE_READ** - Linux only (since Linux 5.14) + /// + /// Populate (prefault) page tables readable, faulting in all + /// pages in the range just as if manually reading from each + /// page; however, avoid the actual memory access that would have + /// been performed after handling the fault. + /// + /// In contrast to MAP_POPULATE, MADV_POPULATE_READ does not hide + /// errors, can be applied to (parts of) existing mappings and + /// will always populate (prefault) page tables readable. One + /// example use case is prefaulting a file mapping, reading all + /// file content from disk; however, pages won't be dirtied and + /// consequently won't have to be written back to disk when + /// evicting the pages from memory. + /// + /// Depending on the underlying mapping, map the shared zeropage, + /// preallocate memory or read the underlying file; files with + /// holes might or might not preallocate blocks. If populating + /// fails, a SIGBUS signal is not generated; instead, an error is + /// returned. + /// + /// If MADV_POPULATE_READ succeeds, all page tables have been + /// populated (prefaulted) readable once. If MADV_POPULATE_READ + /// fails, some page tables might have been populated. + /// + /// MADV_POPULATE_READ cannot be applied to mappings without read + /// permissions and special mappings, for example, mappings + /// marked with kernel-internal flags such as VM_PFNMAP or VM_IO, + /// or secret memory regions created using memfd_secret(2). + /// + /// Note that with MADV_POPULATE_READ, the process can be killed + /// at any moment when the system runs out of memory. + #[cfg(target_os = "linux")] + PopulateRead = libc::MADV_POPULATE_READ, + + /// **MADV_POPULATE_WRITE** - Linux only (since Linux 5.14) + /// + /// Populate (prefault) page tables writable, faulting in all + /// pages in the range just as if manually writing to each each + /// page; however, avoid the actual memory access that would have + /// been performed after handling the fault. + /// + /// In contrast to MAP_POPULATE, MADV_POPULATE_WRITE does not + /// hide errors, can be applied to (parts of) existing mappings + /// and will always populate (prefault) page tables writable. + /// One example use case is preallocating memory, breaking any + /// CoW (Copy on Write). + /// + /// Depending on the underlying mapping, preallocate memory or + /// read the underlying file; files with holes will preallocate + /// blocks. If populating fails, a SIGBUS signal is not gener‐ + /// ated; instead, an error is returned. + /// + /// If MADV_POPULATE_WRITE succeeds, all page tables have been + /// populated (prefaulted) writable once. If MADV_POPULATE_WRITE + /// fails, some page tables might have been populated. + /// + /// MADV_POPULATE_WRITE cannot be applied to mappings without + /// write permissions and special mappings, for example, mappings + /// marked with kernel-internal flags such as VM_PFNMAP or VM_IO, + /// or secret memory regions created using memfd_secret(2). + /// + /// Note that with MADV_POPULATE_WRITE, the process can be killed + /// at any moment when the system runs out of memory. + #[cfg(target_os = "linux")] + PopulateWrite = libc::MADV_POPULATE_WRITE, + + /// **MADV_ZERO_WIRED_PAGES** - Darwin only + /// + /// Indicates that the application would like the wired pages in this address range to be + /// zeroed out if the address range is deallocated without first unwiring the pages (i.e. + /// a munmap(2) without a preceding munlock(2) or the application quits). This is used + /// with madvise() system call. + #[cfg(any(target_os = "macos", target_os = "ios"))] + ZeroWiredPages = libc::MADV_ZERO_WIRED_PAGES, +} + +/// Values supported by [`Mmap::unsafe_advise`][crate::Mmap::unsafe_advise] and [`MmapMut::unsafe_advise`][crate::MmapMut::unsafe_advise] functions. +/// +/// These flags can be passed to the [madvise (2)][man_page] system call +/// and effects on the mapped pages which are conceptually writes, +/// i.e. the change the observable contents of these pages which +/// implies undefined behaviour if the mapping is still borrowed. +/// +/// Hence, these potentially unsafe flags must be used with the unsafe +/// methods and the programmer has to justify that the code +/// does not keep any borrows of the mapping active while the mapped pages +/// are updated by the kernel's memory management subsystem. +/// +/// [man_page]: https://man7.org/linux/man-pages/man2/madvise.2.html +#[repr(i32)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum UncheckedAdvice { + /// **MADV_DONTNEED** + /// + /// Do not expect access in the near future. (For the time + /// being, the application is finished with the given range, + /// so the kernel can free resources associated with it.) + /// + /// After a successful MADV_DONTNEED operation, the semantics + /// of memory access in the specified region are changed: + /// subsequent accesses of pages in the range will succeed, + /// but will result in either repopulating the memory contents + /// from the up-to-date contents of the underlying mapped file + /// (for shared file mappings, shared anonymous mappings, and + /// shmem-based techniques such as System V shared memory + /// segments) or zero-fill-on-demand pages for anonymous + /// private mappings. + /// + /// Note that, when applied to shared mappings, MADV_DONTNEED + /// might not lead to immediate freeing of the pages in the + /// range. The kernel is free to delay freeing the pages + /// until an appropriate moment. The resident set size (RSS) + /// of the calling process will be immediately reduced + /// however. + /// + /// **MADV_DONTNEED** cannot be applied to locked pages, Huge TLB + /// pages, or VM_PFNMAP pages. (Pages marked with the kernel- + /// internal VM_PFNMAP flag are special memory areas that are + /// not managed by the virtual memory subsystem. Such pages + /// are typically created by device drivers that map the pages + /// into user space.) + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping when the pages + /// are freed results in undefined behaviour. + DontNeed = libc::MADV_DONTNEED, + + // + // The rest are Linux-specific + // + /// **MADV_FREE** - Linux (since Linux 4.5) and Darwin + /// + /// The application no longer requires the pages in the range + /// specified by addr and len. The kernel can thus free these + /// pages, but the freeing could be delayed until memory + /// pressure occurs. For each of the pages that has been + /// marked to be freed but has not yet been freed, the free + /// operation will be canceled if the caller writes into the + /// page. After a successful MADV_FREE operation, any stale + /// data (i.e., dirty, unwritten pages) will be lost when the + /// kernel frees the pages. However, subsequent writes to + /// pages in the range will succeed and then kernel cannot + /// free those dirtied pages, so that the caller can always + /// see just written data. If there is no subsequent write, + /// the kernel can free the pages at any time. Once pages in + /// the range have been freed, the caller will see zero-fill- + /// on-demand pages upon subsequent page references. + /// + /// The MADV_FREE operation can be applied only to private + /// anonymous pages (see mmap(2)). In Linux before version + /// 4.12, when freeing pages on a swapless system, the pages + /// in the given range are freed instantly, regardless of + /// memory pressure. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping while the pages + /// are still being freed results in undefined behaviour. + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "ios"))] + Free = libc::MADV_FREE, + + /// **MADV_REMOVE** - Linux only (since Linux 2.6.16) + /// + /// Free up a given range of pages and its associated backing + /// store. This is equivalent to punching a hole in the + /// corresponding byte range of the backing store (see + /// fallocate(2)). Subsequent accesses in the specified + /// address range will see bytes containing zero. + /// + /// The specified address range must be mapped shared and + /// writable. This flag cannot be applied to locked pages, + /// Huge TLB pages, or VM_PFNMAP pages. + /// + /// In the initial implementation, only tmpfs(5) was supported + /// **MADV_REMOVE**; but since Linux 3.5, any filesystem which + /// supports the fallocate(2) FALLOC_FL_PUNCH_HOLE mode also + /// supports MADV_REMOVE. Hugetlbfs fails with the error + /// EINVAL and other filesystems fail with the error + /// EOPNOTSUPP. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping when the pages + /// are freed results in undefined behaviour. + #[cfg(target_os = "linux")] + Remove = libc::MADV_REMOVE, + + /// **MADV_FREE_REUSABLE** - Darwin only + /// + /// Behaves like **MADV_FREE**, but the freed pages are accounted for in the RSS of the process. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping while the pages + /// are still being freed results in undefined behaviour. + #[cfg(any(target_os = "macos", target_os = "ios"))] + FreeReusable = libc::MADV_FREE_REUSABLE, + + /// **MADV_FREE_REUSE** - Darwin only + /// + /// Marks a memory region previously freed by **MADV_FREE_REUSABLE** as non-reusable, accounts + /// for the pages in the RSS of the process. Pages that have been freed will be replaced by + /// zero-filled pages on demand, other pages will be left as is. + /// + /// # Safety + /// + /// Using the returned value with conceptually write to the + /// mapped pages, i.e. borrowing the mapping while the pages + /// are still being freed results in undefined behaviour. + #[cfg(any(target_os = "macos", target_os = "ios"))] + FreeReuse = libc::MADV_FREE_REUSE, +} + +// Future expansion: +// MADV_SOFT_OFFLINE (since Linux 2.6.33) +// MADV_WIPEONFORK (since Linux 4.14) +// MADV_KEEPONFORK (since Linux 4.14) +// MADV_COLD (since Linux 5.4) +// MADV_PAGEOUT (since Linux 5.4) |