@@ -112,8 +112,8 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
112112 loop {
113113 let mem_state = Memstate :: new ( ) . await ?;
114114
115- let mem_total = mem_state. mem_total as f64 * 1024. ;
116- let mem_free = mem_state. mem_free as f64 * 1024. ;
115+ let mem_total = mem_state. mem_total as f64 ;
116+ let mem_free = mem_state. mem_free as f64 ;
117117
118118 // TODO: possibly remove this as it is confusing to have `mem_total_used` and `mem_used`
119119 // htop and such only display equivalent of `mem_used`
@@ -126,8 +126,7 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
126126 min ( mem_state. mem_available , mem_state. mem_total )
127127 } else {
128128 mem_state. mem_free
129- } as f64
130- * 1024. ;
129+ } as f64 ;
131130
132131 // While zfs_arc_cache can be considered "available" memory,
133132 // it can only free a maximum of (zfs_arc_cache - zfs_arc_min) amount.
@@ -137,34 +136,30 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
137136 . saturating_sub ( mem_state. zfs_arc_min ) as f64 ;
138137 let mem_avail = mem_avail + zfs_shrinkable_size;
139138
140- let pagecache = mem_state. pagecache as f64 * 1024. ;
141- let reclaimable = mem_state. s_reclaimable as f64 * 1024. ;
142- let shmem = mem_state. shmem as f64 * 1024. ;
139+ let pagecache = mem_state. pagecache as f64 ;
140+ let reclaimable = mem_state. s_reclaimable as f64 ;
141+ let shmem = mem_state. shmem as f64 ;
143142
144143 // See https://lore.kernel.org/lkml/[email protected] / 145144 let cached = pagecache + reclaimable - shmem + zfs_shrinkable_size;
146145
147- let buffers = mem_state. buffers as f64 * 1024. ;
146+ let buffers = mem_state. buffers as f64 ;
148147
149- // same logic as htop
150- let used_diff = mem_free + buffers + pagecache + reclaimable;
151- let mem_used = if mem_total >= used_diff {
152- mem_total - used_diff
153- } else {
154- mem_total - mem_free
155- } ;
148+ // Userspace should use `mem_avail` for estimating the memory that is available.
149+ // See: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
150+ let mem_used = mem_total - mem_avail;
156151
157152 // account for ZFS ARC cache
158153 let mem_used = mem_used - zfs_shrinkable_size;
159154
160- let swap_total = mem_state. swap_total as f64 * 1024. ;
161- let swap_free = mem_state. swap_free as f64 * 1024. ;
162- let swap_cached = mem_state. swap_cached as f64 * 1024. ;
155+ let swap_total = mem_state. swap_total as f64 ;
156+ let swap_free = mem_state. swap_free as f64 ;
157+ let swap_cached = mem_state. swap_cached as f64 ;
163158 let swap_used = swap_total - swap_free - swap_cached;
164159
165160 // Zswap usage
166- let zswap_compressed = mem_state. zswap_compressed as f64 * 1024. ;
167- let zswap_decompressed = mem_state. zswap_decompressed as f64 * 1024. ;
161+ let zswap_compressed = mem_state. zswap_compressed as f64 ;
162+ let zswap_decompressed = mem_state. zswap_decompressed as f64 ;
168163
169164 let zswap_comp_ratio = if zswap_compressed != 0.0 {
170165 zswap_decompressed / zswap_compressed
@@ -310,19 +305,23 @@ impl Memstate {
310305 . and_then ( |x| u64:: from_str ( x) . ok ( ) )
311306 . error ( "failed to parse /proc/meminfo" ) ?;
312307
308+ // These values are reported as “kB” but are actually “kiB”.
309+ // Convert them into bytes to avoid having to handle this later.
310+ // Source: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo#s2-proc-meminfo
311+ const KIB : u64 = 1024 ;
313312 match name {
314- "MemTotal:" => mem_state. mem_total = val,
315- "MemFree:" => mem_state. mem_free = val,
316- "MemAvailable:" => mem_state. mem_available = val,
317- "Buffers:" => mem_state. buffers = val,
318- "Cached:" => mem_state. pagecache = val,
319- "SReclaimable:" => mem_state. s_reclaimable = val,
320- "Shmem:" => mem_state. shmem = val,
321- "SwapTotal:" => mem_state. swap_total = val,
322- "SwapFree:" => mem_state. swap_free = val,
323- "SwapCached:" => mem_state. swap_cached = val,
324- "Zswap:" => mem_state. zswap_compressed = val,
325- "Zswapped:" => mem_state. zswap_decompressed = val,
313+ "MemTotal:" => mem_state. mem_total = val * KIB ,
314+ "MemFree:" => mem_state. mem_free = val * KIB ,
315+ "MemAvailable:" => mem_state. mem_available = val * KIB ,
316+ "Buffers:" => mem_state. buffers = val * KIB ,
317+ "Cached:" => mem_state. pagecache = val * KIB ,
318+ "SReclaimable:" => mem_state. s_reclaimable = val * KIB ,
319+ "Shmem:" => mem_state. shmem = val * KIB ,
320+ "SwapTotal:" => mem_state. swap_total = val * KIB ,
321+ "SwapFree:" => mem_state. swap_free = val * KIB ,
322+ "SwapCached:" => mem_state. swap_cached = val * KIB ,
323+ "Zswap:" => mem_state. zswap_compressed = val * KIB ,
324+ "Zswapped:" => mem_state. zswap_decompressed = val * KIB ,
326325 _ => ( ) ,
327326 }
328327
0 commit comments