1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
//! Memory management tuning buffer and cache management
//!
//! The files in this directory can be used to tune
//! the operation of the virtual memory (VM) subsystem of the Linux kernel
//! and the write out of dirty data to disk.
use std::fmt;
use std::str;
use crate::{read_value, write_value, ProcResult};
/// The amount of free memory in the system that should be reserved for users with the capability cap_sys_admin.
///
/// # Example
///
/// ```
/// use procfs::sys::vm::admin_reserve_kbytes;
///
/// assert_ne!(admin_reserve_kbytes().unwrap(), 0);
/// ```
pub fn admin_reserve_kbytes() -> ProcResult<usize> {
read_value("/proc/sys/vm/admin_reserve_kbytes")
}
/// Set the amount of free memory in the system that should be reserved for users with the capability cap_sys_admin.
pub fn set_admin_reserve_kbytes(kbytes: usize) -> ProcResult<()> {
write_value("/proc/sys/vm/admin_reserve_kbytes", kbytes)
}
/// Force all zones are compacted such that free memory is available in contiguous blocks where possible.
///
/// This can be important for example in the allocation of huge pages
/// although processes will also directly compact memory as required.
///
/// Present only if the kernel was configured with CONFIG_COMPACTION.
pub fn compact_memory() -> ProcResult<()> {
write_value("/proc/sys/vm/compact_memory", 1)
}
/// drop clean caches, dentries, and inodes from memory, causing that memory to become free.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DropCache {
/// default
Default = 0,
/// free pagecache
PageCache = 1,
/// free dentries and inodes
Inodes = 2,
/// free pagecache, dentries and inodes
All = 3,
/// disable
Disable = 4,
}
impl fmt::Display for DropCache {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
DropCache::Default => 0,
DropCache::PageCache => 1,
DropCache::Inodes => 2,
DropCache::All => 3,
DropCache::Disable => 4,
}
)
}
}
impl str::FromStr for DropCache {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map_err(|_| "Fail to parse drop cache").and_then(|n| match n {
0 => Ok(DropCache::Default),
1 => Ok(DropCache::PageCache),
2 => Ok(DropCache::Inodes),
3 => Ok(DropCache::All),
4 => Ok(DropCache::Disable),
_ => Err("Unknown drop cache value"),
})
}
}
/// Causes the kernel to drop clean caches, dentries, and inodes from memory,
/// causing that memory to become free.
///
/// This can be useful for memory management testing and performing reproducible filesystem benchmarks.
/// Because writing to this file causes the benefits of caching to be lost,
/// it can degrade overall system performance.
pub fn drop_caches(drop: DropCache) -> ProcResult<()> {
write_value("/proc/sys/vm/drop_caches", drop)
}
/// The maximum number of memory map areas a process may have.
///
/// Memory map areas are used as a side-effect of calling malloc,
/// directly by mmap, mprotect, and madvise, and also when loading shared libraries.
///
/// # Example
///
/// ```
/// use procfs::sys::vm::max_map_count;
///
/// assert_ne!(max_map_count().unwrap(), 0);
/// ```
pub fn max_map_count() -> ProcResult<u64> {
read_value("/proc/sys/vm/max_map_count")
}
/// Set the maximum number of memory map areas a process may have.
///
/// Memory map areas are used as a side-effect of calling malloc,
/// directly by mmap, mprotect, and madvise, and also when loading shared libraries.
pub fn set_max_map_count(count: u64) -> ProcResult<()> {
write_value("/proc/sys/vm/max_map_count", count)
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn test() {
use std::path::Path;
if Path::new("/proc/sys/vm/admin_reserve_kbytes").exists() {
admin_reserve_kbytes().unwrap();
}
if Path::new("/proc/sys/vm/max_map_count").exists() {
max_map_count().unwrap();
}
for v in 0..5 {
let s = format!("{}", v);
let dc = DropCache::from_str(&s).unwrap();
assert_eq!(format!("{}", dc), s);
}
}
}