From e1d1a5cec6db15c05e6b75f06e451c7ffa3fde24 Mon Sep 17 00:00:00 2001 From: Sohaib Date: Mon, 22 Feb 2021 16:45:44 +1100 Subject: [PATCH] Add ZFS ARC statistics and meters to the PCP platform --- Makefile.am | 9 +++++++-- pcp/PCPProcessList.c | 40 ++++++++++++++++++++++++++++++++++++++++ pcp/PCPProcessList.h | 2 ++ pcp/Platform.c | 36 +++++++++++++++++++++++++++++++++++- pcp/Platform.h | 15 +++++++++++++++ 5 files changed, 99 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index c66aa46c..8ae0e1f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -338,7 +338,10 @@ pcp_platform_headers = \ pcp/ProcessField.h \ linux/PressureStallMeter.h \ linux/ZramMeter.h \ - linux/ZramStats.h + linux/ZramStats.h \ + zfs/ZfsArcMeter.h \ + zfs/ZfsArcStats.h \ + zfs/ZfsCompressedArcMeter.h if HTOP_PCP myhtopplatsources = \ @@ -346,7 +349,9 @@ myhtopplatsources = \ pcp/PCPProcessList.c \ pcp/Platform.c \ linux/PressureStallMeter.c \ - linux/ZramMeter.c + linux/ZramMeter.c \ + zfs/ZfsArcMeter.c \ + zfs/ZfsCompressedArcMeter.c myhtopplatheaders = $(pcp_platform_headers) endif diff --git a/pcp/PCPProcessList.c b/pcp/PCPProcessList.c index 0e608b1d..0e7b26d5 100644 --- a/pcp/PCPProcessList.c +++ b/pcp/PCPProcessList.c @@ -733,6 +733,45 @@ static void PCPProcessList_updateHeader(ProcessList* super, const Settings* sett PCPProcessList_updatePerCPUReal(this, PCP_HINV_CPUCLOCK, CPU_FREQUENCY); } +static inline void PCPProcessList_scanZfsArcstats(PCPProcessList* this) { + unsigned long long int dbufSize = 0; + unsigned long long int dnodeSize = 0; + unsigned long long int bonusSize = 0; + pmAtomValue value, + comp, + uncomp; + + if (Metric_values(PCP_ZFS_ARC_ANON_SIZE, &value, 1, PM_TYPE_U64)) + this->zfs.anon = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_C_MAX, &value, 1, PM_TYPE_U64)) + this->zfs.max = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_BONUS_SIZE, &value, 1, PM_TYPE_U64)) + bonusSize = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_DBUF_SIZE, &value, 1, PM_TYPE_U64)) + dbufSize = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_DNODE_SIZE, &value, 1, PM_TYPE_U64)) + dnodeSize = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_COMPRESSED_SIZE, &comp, 1, PM_TYPE_U64)) { + this->zfs.isCompressed = 1; + } + if (Metric_values(PCP_ZFS_ARC_UNCOMPRESSED_SIZE, &uncomp, 1, PM_TYPE_U64)) + if (Metric_values(PCP_ZFS_ARC_HDR_SIZE, &value, 1, PM_TYPE_U64)) + this->zfs.header = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_MFU_SIZE, &value, 1, PM_TYPE_U64)) + this->zfs.MFU = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_MRU_SIZE, &value, 1, PM_TYPE_U64)) + this->zfs.MRU = value.ull / 1024; + if (Metric_values(PCP_ZFS_ARC_SIZE, &value, 1, PM_TYPE_U64)) + this->zfs.size = value.ull / 1024; + + this->zfs.enabled = (this->zfs.size > 0 ? 1 : 0); + this->zfs.other = (dbufSize + dnodeSize + bonusSize) / 1024; + if ( this->zfs.isCompressed ) { + this->zfs.compressed = comp.ull /1024; + this->zfs.uncompressed = uncomp.ull /1024; + } +} + void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { PCPProcessList* this = (PCPProcessList*) super; const Settings* settings = super->settings; @@ -769,6 +808,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { this->timestamp = pmtimevalToReal(×tamp); PCPProcessList_updateHeader(super, settings); + PCPProcessList_scanZfsArcstats(this); /* In pause mode only update global data for meters (CPU, memory, etc) */ if (pauseProcessUpdate) diff --git a/pcp/PCPProcessList.h b/pcp/PCPProcessList.h index 28f1d9ce..70ddfb75 100644 --- a/pcp/PCPProcessList.h +++ b/pcp/PCPProcessList.h @@ -16,6 +16,7 @@ in the source distribution for its full text. #include "ProcessList.h" #include "pcp/Platform.h" #include "UsersTable.h" +#include "zfs/ZfsArcStats.h" typedef enum CPUMetric_ { CPU_TOTAL_TIME, @@ -57,6 +58,7 @@ typedef struct PCPProcessList_ { pmAtomValue* cpu; /* aggregate values for each metric */ pmAtomValue** percpu; /* per-processor values for each metric */ pmAtomValue* values; /* per-processor buffer for just one metric */ + ZfsArcStats zfs; } PCPProcessList; ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); diff --git a/pcp/Platform.c b/pcp/Platform.c index 4ac7c701..37074cc2 100644 --- a/pcp/Platform.c +++ b/pcp/Platform.c @@ -38,10 +38,12 @@ in the source distribution for its full text. #include "TasksMeter.h" #include "UptimeMeter.h" #include "XUtils.h" - #include "linux/PressureStallMeter.h" #include "linux/ZramMeter.h" #include "linux/ZramStats.h" +#include "zfs/ZfsArcMeter.h" +#include "zfs/ZfsArcStats.h" +#include "zfs/ZfsCompressedArcMeter.h" typedef struct Platform_ { int context; /* PMAPI(3) context identifier */ @@ -100,6 +102,8 @@ const MeterClass* const Platform_meterTypes[] = { &PressureStallIOFullMeter_class, &PressureStallMemorySomeMeter_class, &PressureStallMemoryFullMeter_class, + &ZfsArcMeter_class, + &ZfsCompressedArcMeter_class, &ZramMeter_class, &DiskIOMeter_class, &NetworkIOMeter_class, @@ -161,6 +165,18 @@ static const char *Platform_metricNames[] = { [PCP_PSI_MEMSOME] = "kernel.all.pressure.memory.some.avg", [PCP_PSI_MEMFULL] = "kernel.all.pressure.memory.full.avg", + [PCP_ZFS_ARC_ANON_SIZE] = "zfs.arc.anon_size", + [PCP_ZFS_ARC_BONUS_SIZE] = "zfs.arc.bonus_size", + [PCP_ZFS_ARC_COMPRESSED_SIZE] = "zfs.arc.compressed_size", + [PCP_ZFS_ARC_UNCOMPRESSED_SIZE] = "zfs.arc.uncompressed_size", + [PCP_ZFS_ARC_C_MAX] = "zfs.arc.c_max", + [PCP_ZFS_ARC_DBUF_SIZE] = "zfs.arc.dbuf_size", + [PCP_ZFS_ARC_DNODE_SIZE] = "zfs.arc.dnode_size", + [PCP_ZFS_ARC_HDR_SIZE] = "zfs.arc.hdr_size", + [PCP_ZFS_ARC_MFU_SIZE] = "zfs.arc.mfu.size", + [PCP_ZFS_ARC_MRU_SIZE] = "zfs.arc.mru.size", + [PCP_ZFS_ARC_SIZE] = "zfs.arc.size", + [PCP_ZRAM_CAPACITY] = "zram.capacity", [PCP_ZRAM_ORIGINAL] = "zram.mm_stat.data_size.original", [PCP_ZRAM_COMPRESSED] = "zram.mm_stat.data_size.compressed", @@ -562,6 +578,7 @@ double Platform_setCPUValues(Meter* this, int cpu) { void Platform_setMemoryValues(Meter* this) { const ProcessList* pl = this->pl; + const PCPProcessList* ppl = (const PCPProcessList*) pl; long int usedMem = pl->usedMem; long int buffersMem = pl->buffersMem; long int cachedMem = pl->cachedMem; @@ -570,6 +587,11 @@ void Platform_setMemoryValues(Meter* this) { this->values[0] = usedMem; this->values[1] = buffersMem; this->values[2] = cachedMem; + + if (ppl->zfs.enabled != 0) { + this->values[0] -= ppl->zfs.size; + this->values[2] += ppl->zfs.size; + } } void Platform_setSwapValues(Meter* this) { @@ -606,6 +628,18 @@ void Platform_setZramValues(Meter* this) { this->values[1] = stats.usedZramOrig; } +void Platform_setZfsArcValues(Meter* this) { + const PCPProcessList* ppl = (const PCPProcessList*) this->pl; + + ZfsArcMeter_readStats(this, &(ppl->zfs)); +} + +void Platform_setZfsCompressedArcValues(Meter* this) { + const PCPProcessList* ppl = (const PCPProcessList*) this->pl; + + ZfsCompressedArcMeter_readStats(this, &(ppl->zfs)); +} + char* Platform_getProcessEnv(pid_t pid) { pmAtomValue value; if (!Metric_instance(PCP_PROC_ENVIRON, pid, 0, &value, PM_TYPE_STRING)) diff --git a/pcp/Platform.h b/pcp/Platform.h index c9e46b80..eb6b3f10 100644 --- a/pcp/Platform.h +++ b/pcp/Platform.h @@ -62,6 +62,10 @@ void Platform_setSwapValues(Meter* this); void Platform_setZramValues(Meter* this); +void Platform_setZfsArcValues(Meter* this); + +void Platform_setZfsCompressedArcValues(Meter* this); + char* Platform_getProcessEnv(pid_t pid); char* Platform_getInodeFilename(pid_t pid, ino_t inode); @@ -132,6 +136,17 @@ typedef enum Metric_ { PCP_PSI_IOFULL, /* kernel.all.pressure.io.full.avg */ PCP_PSI_MEMSOME, /* kernel.all.pressure.memory.some.avg */ PCP_PSI_MEMFULL, /* kernel.all.pressure.memory.full.avg */ + PCP_ZFS_ARC_ANON_SIZE, /* zfs.arc.anon_size */ + PCP_ZFS_ARC_BONUS_SIZE, /* zfs.arc.bonus_size */ + PCP_ZFS_ARC_COMPRESSED_SIZE, /* zfs.arc.compressed_size */ + PCP_ZFS_ARC_UNCOMPRESSED_SIZE, /* zfs.arc.uncompressed_size */ + PCP_ZFS_ARC_C_MAX, /* zfs.arc.c_max */ + PCP_ZFS_ARC_DBUF_SIZE, /* zfs.arc.dbuf_size */ + PCP_ZFS_ARC_DNODE_SIZE, /* zfs.arc.dnode_size */ + PCP_ZFS_ARC_HDR_SIZE, /* zfs.arc.hdr_size */ + PCP_ZFS_ARC_MFU_SIZE, /* zfs.arc.mfu_size */ + PCP_ZFS_ARC_MRU_SIZE, /* zfs.arc.mru_size */ + PCP_ZFS_ARC_SIZE, /* zfs.arc.size */ PCP_ZRAM_CAPACITY, /* zram.capacity */ PCP_ZRAM_ORIGINAL, /* zram.mm_stat.data_size.original */ PCP_ZRAM_COMPRESSED, /* zram.mm_stat.data_size.compressed */