procfs_core/
kpageflags.rs

1use bitflags::bitflags;
2
3#[cfg(feature = "serde1")]
4use serde::{Deserialize, Serialize};
5
6//const fn genmask(high: usize, low: usize) -> u64 {
7//    let mask_bits = size_of::<u64>() * 8;
8//    (!0 - (1 << low) + 1) & (!0 >> (mask_bits - 1 - high))
9//}
10
11bitflags! {
12    /// Represents the fields and flags in a page table entry for a memory page.
13    #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
14    #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
15    pub struct PhysicalPageFlags: u64 {
16        /// The page is being locked for exclusive access, e.g. by undergoing read/write IO
17        const LOCKED = 1 << 0;
18        /// IO error occurred
19        const ERROR = 1 << 1;
20        /// The page has been referenced since last LRU list enqueue/requeue
21        const REFERENCED = 1 << 2;
22        /// The page has up-to-date data. ie. for file backed page: (in-memory data revision >= on-disk one)
23        const UPTODATE = 1 << 3;
24        /// The page has been written to, hence contains new data. i.e. for file backed page: (in-memory data revision > on-disk one)
25        const DIRTY = 1 << 4;
26        /// The page is in one of the LRU lists
27        const LRU = 1 << 5;
28        /// The page is in the active LRU list
29        const ACTIVE = 1 << 6;
30        /// The page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator. When compound page is used, SLUB/SLQB will only set this flag on the head page; SLOB will not flag it at all
31        const SLAB = 1 << 7;
32        /// The page is being synced to disk
33        const WRITEBACK = 1 << 8;
34        /// The page will be reclaimed soon after its pageout IO completed
35        const RECLAIM = 1 << 9;
36        /// A free memory block managed by the buddy system allocator. The buddy system organizes free memory in blocks of various orders. An order N block has 2^N physically contiguous pages, with the BUDDY flag set for and _only_ for the first page
37        const BUDDY = 1 << 10;
38        /// A memory mapped page
39        const MMAP = 1 << 11;
40        /// A memory mapped page that is not part of a file
41        const ANON = 1 << 12;
42        /// The page is mapped to swap space, i.e. has an associated swap entry
43        const SWAPCACHE = 1 << 13;
44        /// The page is backed by swap/RAM
45        const SWAPBACKED = 1 << 14;
46        /// A compound page with order N consists of 2^N physically contiguous pages. A compound page with order 2 takes the form of “HTTT”, where H donates its head page and T donates its tail page(s). The major consumers of compound pages are hugeTLB pages (<https://www.kernel.org/doc/html/latest/admin-guide/mm/hugetlbpage.html#hugetlbpage>), the SLUB etc. memory allocators and various device drivers. However in this interface, only huge/giga pages are made visible to end users
47        const COMPOUND_HEAD = 1 << 15;
48        /// A compound page tail (see description above)
49        const COMPOUND_TAIL = 1 << 16;
50        /// This is an integral part of a HugeTLB page
51        const HUGE = 1 << 17;
52        /// The page is in the unevictable (non-)LRU list It is somehow pinned and not a candidate for LRU page reclaims, e.g. ramfs pages, shmctl(SHM_LOCK) and mlock() memory segments
53        const UNEVICTABLE = 1 << 18;
54        /// Hardware detected memory corruption on this page: don’t touch the data!
55        const HWPOISON = 1 << 19;
56        /// No page frame exists at the requested address
57        const NOPAGE = 1 << 20;
58        /// Identical memory pages dynamically shared between one or more processes
59        const KSM = 1 << 21;
60        /// Contiguous pages which construct transparent hugepages
61        const THP = 1 << 22;
62        /// The page is logically offline
63        const OFFLINE = 1 << 23;
64        /// Zero page for pfn_zero or huge_zero page
65        const ZERO_PAGE = 1 << 24;
66        /// The page has not been accessed since it was marked idle (see <https://www.kernel.org/doc/html/latest/admin-guide/mm/idle_page_tracking.html#idle-page-tracking>). Note that this flag may be stale in case the page was accessed via a PTE. To make sure the flag is up-to-date one has to read /sys/kernel/mm/page_idle/bitmap first
67        const IDLE = 1 << 25;
68        /// The page is in use as a page table
69        const PGTABLE = 1 << 26;
70
71    }
72}
73
74impl PhysicalPageFlags {
75    pub fn parse_info(info: u64) -> Self {
76        PhysicalPageFlags::from_bits_truncate(info)
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_kpageflags_parsing() {
86        let pagemap_entry: u64 = 0b0000000000000000000000000000000000000000000000000000000000000001;
87        let info = PhysicalPageFlags::parse_info(pagemap_entry);
88        assert!(info == PhysicalPageFlags::LOCKED);
89    }
90}