diff options
author | Ivan Shapovalov <intelfx@intelfx.name> | 2022-12-27 05:16:54 +0400 |
---|---|---|
committer | BenBE <BenBE@geshi.org> | 2023-04-23 16:00:17 +0200 |
commit | 71f5a80d9e312375eff28d2fbb7d8add81f6793c (patch) | |
tree | 94fff570e9f040d961a46059d6155b4abff865b6 /linux | |
parent | 0c8df5f9939cfed393a3740a77ef588ad636bb87 (diff) |
Linux: implement zswap support
On Linux, use zswap to populate "compressed memory" metrics added in the
previous commit.
Fixes #104.
Diffstat (limited to 'linux')
-rw-r--r-- | linux/LinuxProcessList.c | 28 | ||||
-rw-r--r-- | linux/LinuxProcessList.h | 2 | ||||
-rw-r--r-- | linux/Platform.c | 15 | ||||
-rw-r--r-- | linux/ZswapStats.h | 21 |
4 files changed, 65 insertions, 1 deletions
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index a3472c53..2ecdefc3 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -1733,6 +1733,7 @@ errorReadingProcess: } static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { + LinuxProcessList *lpl = (LinuxProcessList *)this; memory_t availableMem = 0; memory_t freeMem = 0; memory_t totalMem = 0; @@ -1743,6 +1744,8 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { memory_t swapCacheMem = 0; memory_t swapFreeMem = 0; memory_t sreclaimableMem = 0; + memory_t zswapCompMem = 0; + memory_t zswapOrigMem = 0; FILE* file = fopen(PROCMEMINFOFILE, "r"); if (!file) @@ -1787,6 +1790,10 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { break; } break; + case 'Z': + tryRead("Zswap:", zswapCompMem); + tryRead("Zswapped:", zswapOrigMem); + break; } #undef tryRead @@ -1812,6 +1819,8 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { this->totalSwap = swapTotalMem; this->usedSwap = swapTotalMem - swapFreeMem - swapCacheMem; this->cachedSwap = swapCacheMem; + lpl->zswap.usedZswapComp = zswapCompMem; + lpl->zswap.usedZswapOrig = zswapOrigMem; } static void LinuxProcessList_scanHugePages(LinuxProcessList* this) { @@ -1870,6 +1879,24 @@ static void LinuxProcessList_scanHugePages(LinuxProcessList* this) { closedir(dir); } +static inline void LinuxProcessList_scanZswapInfo(LinuxProcessList *this) { + long max_pool_percent = 0; + int r; + char buf[256]; + + r = xReadfile("/sys/module/zswap/parameters/max_pool_percent", buf, 256); + if (r <= 0) { + return; + } + max_pool_percent = strtol(buf, NULL, 10); + if (max_pool_percent < 0 || max_pool_percent > 100) { + return; + } + + this->zswap.totalZswapPool = this->super.totalMem * max_pool_percent / 100; + /* the rest of the metrics are set in LinuxProcessList_scanMemoryInfo() */ +} + static inline void LinuxProcessList_scanZramInfo(LinuxProcessList* this) { memory_t totalZram = 0; memory_t usedZramComp = 0; @@ -2222,6 +2249,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { LinuxProcessList_scanHugePages(this); LinuxProcessList_scanZfsArcstats(this); LinuxProcessList_scanZramInfo(this); + LinuxProcessList_scanZswapInfo(this); double period = LinuxProcessList_scanCPUTime(super); diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h index b6c015e3..9cfdf24a 100644 --- a/linux/LinuxProcessList.h +++ b/linux/LinuxProcessList.h @@ -16,6 +16,7 @@ in the source distribution for its full text. #include "ProcessList.h" #include "UsersTable.h" #include "linux/ZramStats.h" +#include "linux/ZswapStats.h" #include "zfs/ZfsArcStats.h" #define HTOP_HUGEPAGE_BASE_SHIFT 16 @@ -85,6 +86,7 @@ typedef struct LinuxProcessList_ { ZfsArcStats zfs; ZramStats zram; + ZswapStats zswap; } LinuxProcessList; #ifndef PROCDIR diff --git a/linux/Platform.c b/linux/Platform.c index 45fee392..8015f55b 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -359,7 +359,7 @@ void Platform_setMemoryValues(Meter* this) { this->values[MEMORY_METER_USED] = pl->usedMem; this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; this->values[MEMORY_METER_SHARED] = pl->sharedMem; - // this->values[MEMORY_METER_COMPRESSED] = "compressed memory, like zswap on linux" + this->values[MEMORY_METER_COMPRESSED] = 0; /* compressed */ this->values[MEMORY_METER_CACHE] = pl->cachedMem; this->values[MEMORY_METER_AVAILABLE] = pl->availableMem; @@ -372,13 +372,26 @@ void Platform_setMemoryValues(Meter* this) { this->values[MEMORY_METER_CACHE] += shrinkableSize; this->values[MEMORY_METER_AVAILABLE] += shrinkableSize; } + + if (lpl->zswap.usedZswapOrig > 0 || lpl->zswap.usedZswapComp > 0) { + this->values[MEMORY_METER_USED] -= lpl->zswap.usedZswapComp; + this->values[MEMORY_METER_COMPRESSED] += lpl->zswap.usedZswapComp; + } } void Platform_setSwapValues(Meter* this) { const ProcessList* pl = this->pl; + const LinuxProcessList* lpl = (const LinuxProcessList*) pl; + this->total = pl->totalSwap; this->values[SWAP_METER_USED] = pl->usedSwap; this->values[SWAP_METER_CACHE] = pl->cachedSwap; + this->values[SWAP_METER_FRONTSWAP] = 0; /* frontswap -- memory that is accounted to swap but resides elsewhere */ + + if (lpl->zswap.usedZswapOrig > 0 || lpl->zswap.usedZswapComp > 0) { + this->values[SWAP_METER_USED] -= lpl->zswap.usedZswapOrig; + this->values[SWAP_METER_FRONTSWAP] += lpl->zswap.usedZswapOrig; + } } void Platform_setZramValues(Meter* this) { diff --git a/linux/ZswapStats.h b/linux/ZswapStats.h new file mode 100644 index 00000000..78771e10 --- /dev/null +++ b/linux/ZswapStats.h @@ -0,0 +1,21 @@ +#ifndef HEADER_ZswapStats +#define HEADER_ZswapStats +/* +htop - ZswapStats.h +(C) 2022 htop dev team +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "ProcessList.h" + +typedef struct ZswapStats_ { + /* maximum size of the zswap pool */ + memory_t totalZswapPool; + /* amount of RAM used by the zswap pool */ + memory_t usedZswapComp; + /* amount of data stored inside the zswap pool */ + memory_t usedZswapOrig; +} ZswapStats; + +#endif |