From 5115597e7fd1fa7bdb5d60d4d79531c273c67519 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 7 Nov 2025 01:55:00 +0700 Subject: [PATCH] Improved compatibility for automatically enabling huge pages on Linux systems without NUMA support. --- src/crypto/common/LinuxMemory.cpp | 94 ++++++++++++++++++++----------- src/crypto/common/LinuxMemory.h | 11 ++-- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/src/crypto/common/LinuxMemory.cpp b/src/crypto/common/LinuxMemory.cpp index 8a00e1c36..a09f5a1c7 100644 --- a/src/crypto/common/LinuxMemory.cpp +++ b/src/crypto/common/LinuxMemory.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2025 SChernykh + * Copyright (c) 2016-2025 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,15 +35,69 @@ constexpr size_t twoMiB = 2U * 1024U * 1024U; constexpr size_t oneGiB = 1024U * 1024U * 1024U; -static inline std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr) +static bool sysfs_write(const std::string &path, uint64_t value) +{ + std::ofstream file(path, std::ios::out | std::ios::binary | std::ios::trunc); + if (!file.is_open()) { + return false; + } + + file << value; + file.flush(); + + return true; +} + + +static int64_t sysfs_read(const std::string &path) +{ + std::ifstream file(path); + if (!file.is_open()) { + return -1; + } + + uint64_t value = 0; + file >> value; + + return value; +} + + +static std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr) { return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, hugePageSize / 1024, nr ? "nr" : "free"); } -static inline bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) { return LinuxMemory::write(sysfs_path(node, hugePageSize, true).c_str(), count); } -static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, false).c_str()); } -static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, true).c_str()); } +static std::string sysfs_path(size_t hugePageSize, bool nr) +{ + return fmt::format("/sys/kernel/mm/hugepages/hugepages-{}kB/{}_hugepages", hugePageSize / 1024, nr ? "nr" : "free"); +} + + +static bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) +{ + if (sysfs_write(sysfs_path(node, hugePageSize, true), count)) { + return true; + } + + return sysfs_write(sysfs_path(hugePageSize, true), count); +} + + +static int64_t sysfs_read_hugepages(uint32_t node, size_t hugePageSize, bool nr) +{ + const int64_t value = sysfs_read(sysfs_path(node, hugePageSize, nr)); + if (value >= 0) { + return value; + } + + return sysfs_read(sysfs_path(hugePageSize, nr)); +} + + +static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return sysfs_read_hugepages(node, hugePageSize, false); } +static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return sysfs_read_hugepages(node, hugePageSize, true); } } // namespace xmrig @@ -62,31 +116,3 @@ bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, size_t hugePageSize return write_nr_hugepages(node, hugePageSize, std::max(nr_hugepages(node, hugePageSize), 0) + (required - available)); } - - -bool xmrig::LinuxMemory::write(const char *path, uint64_t value) -{ - std::ofstream file(path, std::ios::out | std::ios::binary | std::ios::trunc); - if (!file.is_open()) { - return false; - } - - file << value; - file.flush(); - - return true; -} - - -int64_t xmrig::LinuxMemory::read(const char *path) -{ - std::ifstream file(path); - if (!file.is_open()) { - return -1; - } - - uint64_t value = 0; - file >> value; - - return value; -} diff --git a/src/crypto/common/LinuxMemory.h b/src/crypto/common/LinuxMemory.h index 0d71af249..c39f96edc 100644 --- a/src/crypto/common/LinuxMemory.h +++ b/src/crypto/common/LinuxMemory.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2025 SChernykh + * Copyright (c) 2016-2025 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,13 +31,10 @@ class LinuxMemory { public: static bool reserve(size_t size, uint32_t node, size_t hugePageSize); - - static bool write(const char *path, uint64_t value); - static int64_t read(const char *path); }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_LINUXMEMORY_H */ +#endif // XMRIG_LINUXMEMORY_H