diff options
Diffstat (limited to 'src/hardware/sysfs.c')
-rw-r--r-- | src/hardware/sysfs.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/src/hardware/sysfs.c b/src/hardware/sysfs.c index d07df71..80d360e 100644 --- a/src/hardware/sysfs.c +++ b/src/hardware/sysfs.c @@ -149,11 +149,11 @@ short sysfs_get_cpu_caches(SysfsCpuCache **caches, unsigned *caches_nb) short ret = -1; unsigned i, level; char *buf = NULL, *format_str, path[PATH_MAX]; - DIR *dir; *caches_nb = 0; /* count caches */ + DIR *dir; char *cache_dir = SYSFS_CPU_PATH "/cpu0/cache"; dir = opendir(cache_dir); if (!dir) { @@ -285,3 +285,108 @@ void sysfs_free_cpu_caches(SysfsCpuCache **caches, unsigned *caches_nb) *caches_nb = 0; *caches = NULL; } + +short sysfs_has_numa() +{ + struct stat st; + + if (stat(SYSFS_PATH "/node/node0", &st) == 0) { + return 1; + } + + return 0; +} + +short sysfs_get_sizes_of_hugepages(unsigned **sizes, unsigned *sizes_nb) +{ + short ret = -1; + DIR *dir; + + *sizes_nb = 0; + *sizes = NULL; + + /* count all sizes */ + char *sizes_dir = SYSFS_KERNEL_MM "/hugepages"; + dir = opendir(sizes_dir); + if (!dir) { + warn("Failed to read directory: \"%s\"; Error: %s", + sizes_dir, strerror(errno)); + ret = -2; + goto done; + } + while (readdir(dir)) { + (*sizes_nb)++; + } + + /* do not count . and .. */ + *sizes_nb -= 2; + + /* if no size was found */ + if (*sizes_nb < 1) { + warn("Looks like kernel doesn't support huge memory pages."); + ret = -3; + goto done; + } + + /* allocate memory for sizes */ + *sizes = (unsigned *)calloc(*sizes_nb, sizeof(unsigned)); + if (!(*sizes)) { + warn("Failed to allocate memory."); + ret = -4; + goto done; + } + + /* get sizes */ + struct dirent *d; + unsigned i = 0; + rewinddir(dir); + while ((d = readdir(dir)) && i < *sizes_nb) { + if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) { + continue; + } + if (strlen(d->d_name) > 11) { + /* read page size from the dirname, which looks like: hugepages-2048kB */ + if (sscanf(d->d_name + 10, "%u", &(*sizes)[i]) == 1) { + i++; + } + } + } + + ret = 0; + +done: + if (dir) { + closedir(dir); + } + + if (ret != 0) { + *sizes_nb = 0; + free(*sizes); + *sizes = NULL; + } + + return ret; +} + +ThpStatus sysfs_get_transparent_hugepages_status() +{ + ThpStatus ret = thp_unsupported; + char *val = NULL; + + if (path_get_string(SYSFS_KERNEL_MM "/transparent_hugepage/enabled", &val) != 0) { + goto done; + } + + if (strstr(val, "[always]")) { + ret = thp_always; + } else if (strstr(val, "[madvise]")) { + ret = thp_madvise; + } else if (strstr(val, "[never]")) { + ret = thp_never; + } + +done: + free(val); + + return ret; +} |