Memory (Linux): takes ZFS arc bytes into account

Fixes #1995
This commit is contained in:
Carter Li
2026-06-27 17:18:19 +08:00
committed by 李通洲
parent 231d7fcd4d
commit dfdc7284a2
+51 -12
View File
@@ -1,8 +1,5 @@
#include "memory.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <inttypes.h>
const char* ffDetectMemory(FFMemoryResult* ram) {
char buf[PROC_FILE_BUFFSIZ];
@@ -21,34 +18,34 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
sReclaimable = 0;
char* token = NULL;
if ((token = strstr(buf, "MemTotal:")) != NULL) {
if ((token = memmem(buf, (size_t) nRead, "MemTotal:", strlen("MemTotal:"))) != NULL) {
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
} else {
return "MemTotal not found in /proc/meminfo";
}
if ((token = strstr(buf, "MemAvailable:")) != NULL) {
if ((token = memmem(buf, (size_t) nRead, "MemAvailable:", strlen("MemAvailable:"))) != NULL) {
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
}
if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988
{
if ((token = strstr(buf, "MemFree:")) != NULL) {
if (memAvailable == 0 || memAvailable >= memTotal) { // MemAvailable can be unreasonable. #1988
if ((token = memmem(buf, (size_t) nRead, "MemFree:", strlen("MemFree:"))) != NULL) {
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
}
if ((token = strstr(buf, "Buffers:")) != NULL) {
if ((token = memmem(buf, (size_t) nRead, "Buffers:", strlen("Buffers:"))) != NULL) {
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
}
if ((token = strstr(buf, "Cached:")) != NULL) {
if ((token = memmem(buf, (size_t) nRead, "Cached:", strlen("Cached:"))) != NULL) {
cached = strtoul(token + strlen("Cached:"), NULL, 10);
}
if ((token = strstr(buf, "Shmem:")) != NULL) {
if ((token = memmem(buf, (size_t) nRead, "Shmem:", strlen("Shmem:"))) != NULL) {
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
}
if ((token = strstr(buf, "SReclaimable:")) != NULL) {
if ((token = memmem(buf, (size_t) nRead, "SReclaimable:", strlen("SReclaimable:"))) != NULL) {
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
}
@@ -58,5 +55,47 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = memTotal * 1024lu;
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
uint64_t arcSize = 0;
nRead = ffReadFileData("/proc/spl/kstat/zfs/arcstats", ARRAY_SIZE(buf) - 1, buf);
if (nRead > 0) {
buf[nRead] = '\0';
// 24 1 0x01 148 40256 2053603602 851614020716
// name type data
// hits 4 752
// Skip first line
const char* p = memchr(buf, '\n', (size_t) nRead);
if (__builtin_expect(p != NULL, true)) {
++p;
nRead -= (p - buf);
assert(nRead > 0);
// Find line offset of data
const char* pData = memmem(p, (size_t) nRead, "data\n", strlen("data\n"));
if (__builtin_expect(pData != NULL, true)) {
uint32_t dataOffset = (uint32_t) (pData - p);
p += dataOffset + strlen("data\n");
nRead -= (ssize_t) (dataOffset + strlen("data\n"));
assert(nRead > 0);
if ((token = memmem(p, (size_t) nRead, "\nsize ", strlen("\nsize "))) != NULL) {
arcSize = strtoul(token + 1 + dataOffset, NULL, 10);
if (arcSize > 0) {
uint64_t arcMin = 0;
if ((token = memmem(p, (size_t) nRead, "\nc_min ", strlen("\nc_min "))) != NULL) {
arcMin = strtoul(token + 1 + dataOffset, NULL, 10);
if (arcSize > arcMin) {
arcSize -= arcMin;
if (ram->bytesUsed > arcSize) {
ram->bytesUsed -= arcSize;
}
}
}
}
}
}
}
}
return NULL;
}