`numastat -m` gets hugepages memory just from /sys/devices/system/node/node$/meminfo, it is not the entire hugepages memory of the system, just the default huge page. (cherry picked from commit 0bd4d6897b2d2dc6e26e2f71729869127dc42945)
148 lines
5.7 KiB
Diff
148 lines
5.7 KiB
Diff
From 248823314e04437aa85a159d4b532ed544d361f8 Mon Sep 17 00:00:00 2001
|
|
From: Chunsheng Luo <luochunsheng@huawei.com>
|
|
Date: Mon, 12 Dec 2022 12:02:36 +0800
|
|
Subject: [PATCH] numastat: Update system hugepages memory info from
|
|
sysfs/node/hugepages directory
|
|
|
|
`numastat -m` gets hugepages memory just from /sys/devices/system/node/node$/meminfo,
|
|
it is not the entire hugepages memory of the system, just the default huge page.
|
|
|
|
Update the entire hugepages memory information from the /sys/devices/system/node/node$/hugepages directory.
|
|
|
|
Signed-off-by: buque <wuxu.wu@huawei.com>
|
|
---
|
|
numastat.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 95 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/numastat.c b/numastat.c
|
|
index 6a922f3..cc2249f 100644
|
|
--- a/numastat.c
|
|
+++ b/numastat.c
|
|
@@ -41,6 +41,9 @@ end of this file.
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
+#include <dirent.h>
|
|
+#include <sys/stat.h>
|
|
+#include <errno.h>
|
|
|
|
#define STRINGIZE(s) #s
|
|
#define STRINGIFY(s) STRINGIZE(s)
|
|
@@ -50,6 +53,8 @@ end of this file.
|
|
|
|
#define BUF_SIZE 2048
|
|
#define SMALL_BUF_SIZE 128
|
|
+#define PATH_LEN 128
|
|
+#define DNAME_LEN 64
|
|
|
|
// Don't assume nodes are sequential or contiguous.
|
|
// Need to discover and map node numbers.
|
|
@@ -794,6 +799,88 @@ static char *command_name_for_pid(int pid)
|
|
return NULL;
|
|
}
|
|
|
|
+/* update hugepages info from /sys/devices/system/node/node$/hugepages/hugepages-$ */
|
|
+static double update_hugepages_info(int node_ix, const char *token)
|
|
+{
|
|
+ char *fname;
|
|
+ DIR *d = NULL;
|
|
+ struct dirent *dp = NULL;
|
|
+ struct stat st;
|
|
+ char top_path[64];
|
|
+
|
|
+ if (!strncmp(token, "HugePages_Total", 15)) {
|
|
+ fname = "nr_hugepages";
|
|
+ } else if(!strncmp(token, "HugePages_Free", 14)) {
|
|
+ fname = "free_hugepages";
|
|
+ } else if (!strncmp(token, "HugePages_Surp", 14)) {
|
|
+ fname = "surplus_hugepages";
|
|
+ } else {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ snprintf(top_path, sizeof(top_path), "/sys/devices/system/node/node%d/hugepages", node_ix);
|
|
+
|
|
+ if(stat(top_path, &st) < 0 || !S_ISDIR(st.st_mode)) {
|
|
+ printf("invalid path: %s\n", top_path);
|
|
+ return -ENOENT;
|
|
+ }
|
|
+
|
|
+ if(!(d = opendir(top_path))) {
|
|
+ fprintf(stderr, "opendir[%s] error: %s\n", top_path, strerror(errno));
|
|
+ return -ENOENT;
|
|
+ }
|
|
+
|
|
+ const char *delimiters = "-";
|
|
+ double total = 0;
|
|
+ char *huge_dname;
|
|
+ char *fpath;
|
|
+ char *buf;
|
|
+
|
|
+ huge_dname = (char *)malloc(DNAME_LEN);
|
|
+ fpath = (char *)malloc(PATH_LEN);
|
|
+ buf = (char *)malloc(SMALL_BUF_SIZE);
|
|
+
|
|
+ /* Traversing directories /sys/devices/system/node/node%d/hugepages */
|
|
+ while((dp = readdir(d)) != NULL) {
|
|
+ if((!strncmp(dp->d_name, ".", 1)) || (!strncmp(dp->d_name, "..", 2)))
|
|
+ continue;
|
|
+
|
|
+ if ((dp->d_type != DT_DIR) || strncmp(dp->d_name, "hugepages-", 10))
|
|
+ continue;
|
|
+
|
|
+ /* Get huge pages size from d_name d_name: example hugepages-1048576kB */
|
|
+ memset(huge_dname, 0, DNAME_LEN);
|
|
+ memcpy(huge_dname, dp->d_name, strlen(dp->d_name));
|
|
+
|
|
+ /* Example: /sys/devices/system/node/node%d/hugepages/hugepages-1048576kB/nr_hugepages */
|
|
+ snprintf(fpath, PATH_LEN, "%s/%s/%s", top_path, huge_dname, fname);
|
|
+
|
|
+ char *pagesz_str = strtok(huge_dname, delimiters);
|
|
+ pagesz_str = strtok(NULL, pagesz_str);
|
|
+ memset(strstr(pagesz_str, "kB"), 0, 2);
|
|
+ unsigned long hugepage_size = strtol(pagesz_str, NULL, 10);
|
|
+ hugepage_size *= KILOBYTE;
|
|
+
|
|
+ /* Get the number of pages */
|
|
+ FILE *fs = fopen(fpath, "r");
|
|
+ if (!fs) {
|
|
+ printf("cannot open %s: %s\n", fpath, strerror(errno));
|
|
+ continue;
|
|
+ }
|
|
+ fgets(buf, SMALL_BUF_SIZE, fs);
|
|
+ unsigned long nr_pages = strtol(buf, NULL, 10);
|
|
+ fclose(fs);
|
|
+
|
|
+ total += nr_pages * hugepage_size;
|
|
+ }
|
|
+ closedir(d);
|
|
+ free(huge_dname);
|
|
+ free(fpath);
|
|
+ free(buf);
|
|
+
|
|
+ return total;
|
|
+}
|
|
+
|
|
static void show_info_from_system_file(char *file, meminfo_p meminfo, int meminfo_rows, int tok_offset)
|
|
{
|
|
// Setup and init table
|
|
@@ -873,7 +960,14 @@ static void show_info_from_system_file(char *file, meminfo_p meminfo, int meminf
|
|
if (tokens < 4) {
|
|
multiplier = page_size_in_bytes;
|
|
} else if (!strncmp("HugePages", tok[2], 9)) {
|
|
- multiplier = huge_page_size_in_bytes;
|
|
+ /* update hugepages info more detail from sysfs/hugepages directory */
|
|
+ double new = update_hugepages_info(node_ix_map[node_ix], tok[2]);
|
|
+ if (new > 0) {
|
|
+ value = new;
|
|
+ } else {
|
|
+ /* fall back old way */
|
|
+ multiplier = huge_page_size_in_bytes;
|
|
+ }
|
|
} else if (!strncmp("kB", tok[4], 2)) {
|
|
multiplier = KILOBYTE;
|
|
}
|
|
--
|
|
2.33.0
|
|
|