summaryrefslogtreecommitdiffstats
path: root/src/hardware/sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hardware/sysfs.c')
-rw-r--r--src/hardware/sysfs.c107
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;
+}