From a7384483a4e9bc99009cfbf1f2898394ad4222ac Mon Sep 17 00:00:00 2001 From: Matt Ickstadt Date: Fri, 29 Apr 2022 22:08:00 -0500 Subject: [PATCH] Include ZFS ARC in cached/available memory on Linux --- src/btop_config.cpp | 3 +++ src/btop_menu.cpp | 9 +++++++++ src/linux/btop_collect.cpp | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/btop_config.cpp b/src/btop_config.cpp index 61476e1..137b168 100644 --- a/src/btop_config.cpp +++ b/src/btop_config.cpp @@ -141,6 +141,8 @@ namespace Config { {"mem_below_net", "#* Show mem box below net box instead of above."}, + {"zfs_arc_cached", "#* Count ZFS ARC in cached and available memory."}, + {"show_swap", "#* If swap memory should be shown in memory box."}, {"swap_disk", "#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk."}, @@ -230,6 +232,7 @@ namespace Config { {"background_update", true}, {"mem_graphs", true}, {"mem_below_net", false}, + {"zfs_arc_cached", true}, {"show_swap", true}, {"swap_disk", true}, {"show_disks", true}, diff --git a/src/btop_menu.cpp b/src/btop_menu.cpp index 92aea75..65d1639 100644 --- a/src/btop_menu.cpp +++ b/src/btop_menu.cpp @@ -490,6 +490,15 @@ namespace Menu { "", "Example:", "\"exclude=/boot /home/user\""}, + {"zfs_arc_cached", + "(Linux) Count ZFS ARC as cached memory.", + "", + "Add ZFS ARC used to cached memory and", + "ZFS ARC available to available memory.", + "These are otherwise reported by the Linux", + "kernel as used memory.", + "", + "True or False."}, }, { {"graph_symbol_net", diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index 595404d..4c82fef 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -732,6 +732,7 @@ namespace Mem { fs::file_time_type fstab_time; int disk_ios = 0; vector last_found; + const std::regex zfs_size_regex("^size\\s+\\d\\s+(\\d+)"); mem_info current_mem {}; @@ -754,11 +755,28 @@ namespace Mem { auto& show_swap = Config::getB("show_swap"); auto& swap_disk = Config::getB("swap_disk"); auto& show_disks = Config::getB("show_disks"); + auto& zfs_arc_cached = Config::getB("zfs_arc_cached"); auto totalMem = get_totalMem(); auto& mem = current_mem; mem.stats.at("swap_total") = 0; + //? Read ZFS ARC info from /proc/spl/kstat/zfs/arcstats + uint64_t arc_size = 0; + if (zfs_arc_cached) { + ifstream arcstats(Shared::procPath / "spl/kstat/zfs/arcstats"); + if (arcstats.good()) { + std::string line; + while (std::getline(arcstats, line)) { + std::smatch match; + if (std::regex_match(line, match, zfs_size_regex) && match.size() == 2) { + arc_size = stoull(match.str(1)); + } + } + } + arcstats.close(); + } + //? Read memory info from /proc/meminfo ifstream meminfo(Shared::procPath / "meminfo"); if (meminfo.good()) { @@ -790,6 +808,10 @@ namespace Mem { meminfo.ignore(SSmax, '\n'); } if (not got_avail) mem.stats.at("available") = mem.stats.at("free") + mem.stats.at("cached"); + if (zfs_arc_cached) { + mem.stats.at("cached") += arc_size; + mem.stats.at("available") += arc_size; + } mem.stats.at("used") = totalMem - mem.stats.at("available"); if (mem.stats.at("swap_total") > 0) mem.stats.at("swap_used") = mem.stats.at("swap_total") - mem.stats.at("swap_free"); }