From d23e5e15ba655b020d350b32cfee302fd63c6ba3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 14 Feb 2020 23:37:44 +0700 Subject: [PATCH] Added AMD GPUs health information for Linux (via sysfs). --- CMakeLists.txt | 2 +- src/backend/opencl/opencl.cmake | 8 +- src/backend/opencl/wrappers/AdlLib.cpp | 3 +- src/backend/opencl/wrappers/AdlLib_linux.cpp | 138 +++++++++++++++++++ 4 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 src/backend/opencl/wrappers/AdlLib_linux.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f63c535..e20cd42a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF) option(WITH_OPENCL "Enable OpenCL backend" ON) option(WITH_CUDA "Enable CUDA backend" ON) option(WITH_NVML "Enable NVML (NVIDIA Management Library) support (only if CUDA backend enabled)" ON) -option(WITH_ADL "Enable ADL (AMD Display Library) support (only if OpenCL backend enabled)" ON) +option(WITH_ADL "Enable ADL (AMD Display Library) or sysfs support (only if OpenCL backend enabled)" ON) option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON) option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF) diff --git a/src/backend/opencl/opencl.cmake b/src/backend/opencl/opencl.cmake index 565ccd11..535e1a73 100644 --- a/src/backend/opencl/opencl.cmake +++ b/src/backend/opencl/opencl.cmake @@ -127,7 +127,7 @@ if (WITH_OPENCL) add_definitions(/DXMRIG_INTERLEAVE_DEBUG) endif() - if (WITH_ADL AND XMRIG_OS_WIN) + if (WITH_ADL AND (XMRIG_OS_WIN OR XMRIG_OS_LINUX)) add_definitions(/DXMRIG_FEATURE_ADL) list(APPEND HEADERS_BACKEND_OPENCL @@ -135,7 +135,11 @@ if (WITH_OPENCL) src/backend/opencl/wrappers/AdlLib.h ) - list(APPEND SOURCES_BACKEND_OPENCL src/backend/opencl/wrappers/AdlLib.cpp) + if (XMRIG_OS_WIN) + list(APPEND SOURCES_BACKEND_OPENCL src/backend/opencl/wrappers/AdlLib.cpp) + else() + list(APPEND SOURCES_BACKEND_OPENCL src/backend/opencl/wrappers/AdlLib_linux.cpp) + endif() else() remove_definitions(/DXMRIG_FEATURE_ADL) endif() diff --git a/src/backend/opencl/wrappers/AdlLib.cpp b/src/backend/opencl/wrappers/AdlLib.cpp index ddcc2fb8..d3b3bef4 100644 --- a/src/backend/opencl/wrappers/AdlLib.cpp +++ b/src/backend/opencl/wrappers/AdlLib.cpp @@ -25,7 +25,6 @@ #include "backend/opencl/wrappers/AdlLib.h" #include "3rdparty/adl/adl_sdk.h" #include "3rdparty/adl/adl_structures.h" -#include "base/io/log/Log.h" #include "backend/opencl/wrappers/OclDevice.h" @@ -188,7 +187,7 @@ void xmrig::AdlLib::close() AdlHealth xmrig::AdlLib::health(const OclDevice &device) { - if (!isReady()) { + if (!isReady() || device.vendorId() != OCL_VENDOR_AMD) { return {}; } diff --git a/src/backend/opencl/wrappers/AdlLib_linux.cpp b/src/backend/opencl/wrappers/AdlLib_linux.cpp new file mode 100644 index 00000000..5ef0e5e5 --- /dev/null +++ b/src/backend/opencl/wrappers/AdlLib_linux.cpp @@ -0,0 +1,138 @@ +/* XMRig + * Copyright 2008-2018 Advanced Micro Devices, Inc. + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/opencl/wrappers/AdlLib.h" +#include "backend/opencl/wrappers/OclDevice.h" + + +#include +#include +#include +#include + + +namespace xmrig { + + +bool AdlLib::m_initialized = false; +bool AdlLib::m_ready = false; +static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/"; + + +static inline bool sysfs_is_file(const char *path) +{ + struct stat sb; + + return stat(path, &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG); +} + + +static inline std::string sysfs_prefix(const PciTopology &topology) +{ + std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon"; + + if (sysfs_is_file((path + "2/name").c_str())) { + return path + "2/"; + } + + if (sysfs_is_file((path + "3/name").c_str())) { + return path + "3/"; + } + + return {}; +} + + +uint32_t sysfs_read(const std::string &path) +{ + std::ifstream file(path); + if (!file.is_open()) { + return 0; + } + + uint32_t value = 0; + file >> value; + + return value; +} + + +} // namespace xmrig + + +bool xmrig::AdlLib::init() +{ + if (!m_initialized) { + m_ready = dlopen() && load(); + m_initialized = true; + } + + return m_ready; +} + + +const char *xmrig::AdlLib::lastError() noexcept +{ + return nullptr; +} + + +void xmrig::AdlLib::close() +{ +} + + +AdlHealth xmrig::AdlLib::health(const OclDevice &device) +{ + if (!isReady() || device.vendorId() != OCL_VENDOR_AMD) { + return {}; + } + + const auto prefix = sysfs_prefix(device.topology()); + if (prefix.empty()) { + return {}; + } + + AdlHealth health; + health.clock = sysfs_read(prefix + "freq1_input") / 1000000; + health.memClock = sysfs_read(prefix + "freq2_input") / 1000000; + health.power = sysfs_read(prefix + "power1_average") / 1000000; + health.rpm = sysfs_read(prefix + "fan1_input"); + health.temperature = sysfs_read(prefix + "temp2_input") / 1000; + + return health; +} + + +bool xmrig::AdlLib::dlopen() +{ + struct stat sb; + if (stat(kPrefix.c_str(), &sb) == -1) { + return false; + } + + return (sb.st_mode & S_IFMT) == S_IFDIR; +} + + +bool xmrig::AdlLib::load() +{ + return true; +}