Linux: implement zswap support

On Linux, use zswap to populate "compressed memory" metrics added in the
previous commit.

Fixes #104.
portage
Ivan Shapovalov 3 years ago committed by BenBE
parent 0c8df5f993
commit 71f5a80d9e
  1. 1
      Makefile.am
  2. 28
      linux/LinuxProcessList.c
  3. 2
      linux/LinuxProcessList.h
  4. 15
      linux/Platform.c
  5. 21
      linux/ZswapStats.h

@ -173,6 +173,7 @@ linux_platform_headers = \
linux/SystemdMeter.h \ linux/SystemdMeter.h \
linux/ZramMeter.h \ linux/ZramMeter.h \
linux/ZramStats.h \ linux/ZramStats.h \
linux/ZswapStats.h \
zfs/ZfsArcMeter.h \ zfs/ZfsArcMeter.h \
zfs/ZfsArcStats.h \ zfs/ZfsArcStats.h \
zfs/ZfsCompressedArcMeter.h zfs/ZfsCompressedArcMeter.h

@ -1733,6 +1733,7 @@ errorReadingProcess:
} }
static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
LinuxProcessList *lpl = (LinuxProcessList *)this;
memory_t availableMem = 0; memory_t availableMem = 0;
memory_t freeMem = 0; memory_t freeMem = 0;
memory_t totalMem = 0; memory_t totalMem = 0;
@ -1743,6 +1744,8 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
memory_t swapCacheMem = 0; memory_t swapCacheMem = 0;
memory_t swapFreeMem = 0; memory_t swapFreeMem = 0;
memory_t sreclaimableMem = 0; memory_t sreclaimableMem = 0;
memory_t zswapCompMem = 0;
memory_t zswapOrigMem = 0;
FILE* file = fopen(PROCMEMINFOFILE, "r"); FILE* file = fopen(PROCMEMINFOFILE, "r");
if (!file) if (!file)
@ -1787,6 +1790,10 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
break; break;
} }
break; break;
case 'Z':
tryRead("Zswap:", zswapCompMem);
tryRead("Zswapped:", zswapOrigMem);
break;
} }
#undef tryRead #undef tryRead
@ -1812,6 +1819,8 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
this->totalSwap = swapTotalMem; this->totalSwap = swapTotalMem;
this->usedSwap = swapTotalMem - swapFreeMem - swapCacheMem; this->usedSwap = swapTotalMem - swapFreeMem - swapCacheMem;
this->cachedSwap = swapCacheMem; this->cachedSwap = swapCacheMem;
lpl->zswap.usedZswapComp = zswapCompMem;
lpl->zswap.usedZswapOrig = zswapOrigMem;
} }
static void LinuxProcessList_scanHugePages(LinuxProcessList* this) { static void LinuxProcessList_scanHugePages(LinuxProcessList* this) {
@ -1870,6 +1879,24 @@ static void LinuxProcessList_scanHugePages(LinuxProcessList* this) {
closedir(dir); 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) { static inline void LinuxProcessList_scanZramInfo(LinuxProcessList* this) {
memory_t totalZram = 0; memory_t totalZram = 0;
memory_t usedZramComp = 0; memory_t usedZramComp = 0;
@ -2222,6 +2249,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
LinuxProcessList_scanHugePages(this); LinuxProcessList_scanHugePages(this);
LinuxProcessList_scanZfsArcstats(this); LinuxProcessList_scanZfsArcstats(this);
LinuxProcessList_scanZramInfo(this); LinuxProcessList_scanZramInfo(this);
LinuxProcessList_scanZswapInfo(this);
double period = LinuxProcessList_scanCPUTime(super); double period = LinuxProcessList_scanCPUTime(super);

@ -16,6 +16,7 @@ in the source distribution for its full text.
#include "ProcessList.h" #include "ProcessList.h"
#include "UsersTable.h" #include "UsersTable.h"
#include "linux/ZramStats.h" #include "linux/ZramStats.h"
#include "linux/ZswapStats.h"
#include "zfs/ZfsArcStats.h" #include "zfs/ZfsArcStats.h"
#define HTOP_HUGEPAGE_BASE_SHIFT 16 #define HTOP_HUGEPAGE_BASE_SHIFT 16
@ -85,6 +86,7 @@ typedef struct LinuxProcessList_ {
ZfsArcStats zfs; ZfsArcStats zfs;
ZramStats zram; ZramStats zram;
ZswapStats zswap;
} LinuxProcessList; } LinuxProcessList;
#ifndef PROCDIR #ifndef PROCDIR

@ -359,7 +359,7 @@ void Platform_setMemoryValues(Meter* this) {
this->values[MEMORY_METER_USED] = pl->usedMem; this->values[MEMORY_METER_USED] = pl->usedMem;
this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; this->values[MEMORY_METER_BUFFERS] = pl->buffersMem;
this->values[MEMORY_METER_SHARED] = pl->sharedMem; 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_CACHE] = pl->cachedMem;
this->values[MEMORY_METER_AVAILABLE] = pl->availableMem; 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_CACHE] += shrinkableSize;
this->values[MEMORY_METER_AVAILABLE] += 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) { void Platform_setSwapValues(Meter* this) {
const ProcessList* pl = this->pl; const ProcessList* pl = this->pl;
const LinuxProcessList* lpl = (const LinuxProcessList*) pl;
this->total = pl->totalSwap; this->total = pl->totalSwap;
this->values[SWAP_METER_USED] = pl->usedSwap; this->values[SWAP_METER_USED] = pl->usedSwap;
this->values[SWAP_METER_CACHE] = pl->cachedSwap; 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) { void Platform_setZramValues(Meter* this) {

@ -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
Loading…
Cancel
Save