hwloc: Clarify reason for failed binding ("can't bind memory")

This commit is contained in:
Tony Butler 2024-05-30 07:23:25 -06:00
parent 5eaa6c152e
commit 14128cbdb4
5 changed files with 45 additions and 16 deletions

View file

@ -29,6 +29,10 @@
#ifdef XMRIG_FEATURE_HWLOC #ifdef XMRIG_FEATURE_HWLOC
using hwloc_const_bitmap_t = const struct hwloc_bitmap_s *; using hwloc_const_bitmap_t = const struct hwloc_bitmap_s *;
using hwloc_topology_t = struct hwloc_topology *; using hwloc_topology_t = struct hwloc_topology *;
#define MEMBIND_SUCCESS 1
#define MEMBIND_FAIL_SUPP -1
#define MEMBIND_FAIL_NODE -2
#define MEMBIND_FAIL_BIND -3
#endif #endif
@ -124,7 +128,7 @@ public:
virtual uint32_t model() const = 0; virtual uint32_t model() const = 0;
# ifdef XMRIG_FEATURE_HWLOC # ifdef XMRIG_FEATURE_HWLOC
virtual bool membind(hwloc_const_bitmap_t nodeset) = 0; virtual int8_t membind(hwloc_const_bitmap_t nodeset) = 0;
virtual const std::vector<uint32_t> &nodeset() const = 0; virtual const std::vector<uint32_t> &nodeset() const = 0;
virtual hwloc_topology_t topology() const = 0; virtual hwloc_topology_t topology() const = 0;
# endif # endif

View file

@ -23,6 +23,7 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <errno.h>
#include <hwloc.h> #include <hwloc.h>
@ -191,16 +192,25 @@ xmrig::HwlocCpuInfo::~HwlocCpuInfo()
} }
bool xmrig::HwlocCpuInfo::membind(hwloc_const_bitmap_t nodeset) int8_t xmrig::HwlocCpuInfo::membind(hwloc_const_bitmap_t nodeset)
{ {
if (!hwloc_topology_get_support(m_topology)->membind->set_thisthread_membind) { if (!hwloc_topology_get_support(m_topology)->membind->set_thisthread_membind) {
return false; return MEMBIND_FAIL_SUPP;
} }
# if HWLOC_API_VERSION >= 0x20000 # if HWLOC_API_VERSION >= 0x20000
return hwloc_set_membind(m_topology, nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET) >= 0; int rv = hwloc_set_membind(m_topology, nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET);
int error = errno;
if (rv < 0) {
LOG_WARN("hwloc_set_membind() error: \"%s\"\n", strerror(error));
return MEMBIND_FAIL_BIND;
}
return MEMBIND_SUCCESS;
# else # else
return hwloc_set_membind_nodeset(m_topology, nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD) >= 0; return (hwloc_set_membind_nodeset(m_topology, nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD) >= 0)
? MEMBIND_SUCCESS : MEMBIND_FAIL_BIND;
# endif # endif
} }

View file

@ -38,7 +38,7 @@ public:
~HwlocCpuInfo() override; ~HwlocCpuInfo() override;
protected: protected:
bool membind(hwloc_const_bitmap_t nodeset) override; int8_t membind(hwloc_const_bitmap_t nodeset) override;
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline const char *backend() const override { return m_backend; } inline const char *backend() const override { return m_backend; }

View file

@ -34,8 +34,13 @@ uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t affinity)
auto pu = hwloc_get_pu_obj_by_os_index(Cpu::info()->topology(), static_cast<unsigned>(affinity)); auto pu = hwloc_get_pu_obj_by_os_index(Cpu::info()->topology(), static_cast<unsigned>(affinity));
if (pu == nullptr || !Cpu::info()->membind(pu->nodeset)) { if (pu == nullptr) {
LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity); LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory: hwloc_get_pu_obj_by_os_index() failed\"", affinity);
return 0;
}
if (Cpu::info()->membind(pu->nodeset) < 0) {
LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory: Cpu::info()->membind() failed\"", affinity);
return 0; return 0;
} }

View file

@ -42,20 +42,20 @@ constexpr size_t oneMiB = 1024 * 1024;
static std::mutex mutex; static std::mutex mutex;
static bool bindToNUMANode(uint32_t nodeId) static int8_t bindToNUMANode(uint32_t nodeId)
{ {
auto node = hwloc_get_numanode_obj_by_os_index(Cpu::info()->topology(), nodeId); auto node = hwloc_get_numanode_obj_by_os_index(Cpu::info()->topology(), nodeId);
if (!node) { if (!node) {
return false; return MEMBIND_FAIL_NODE;
} }
if (Cpu::info()->membind(node->nodeset)) { if (Cpu::info()->membind(node->nodeset) > 0) {
Platform::setThreadAffinity(static_cast<uint64_t>(hwloc_bitmap_first(node->cpuset))); Platform::setThreadAffinity(static_cast<uint64_t>(hwloc_bitmap_first(node->cpuset)));
return true; return MEMBIND_SUCCESS;
} }
return false; return MEMBIND_FAIL_BIND;
} }
@ -210,10 +210,20 @@ private:
static void allocate(RxNUMAStoragePrivate *d_ptr, uint32_t nodeId, bool hugePages, bool oneGbPages) static void allocate(RxNUMAStoragePrivate *d_ptr, uint32_t nodeId, bool hugePages, bool oneGbPages)
{ {
const uint64_t ts = Chrono::steadyMSecs(); const uint64_t ts = Chrono::steadyMSecs();
const int8_t br = bindToNUMANode(nodeId);
if (!bindToNUMANode(nodeId)) { if (br < 0) {
printSkipped(nodeId, "can't bind memory"); switch (br) {
case MEMBIND_FAIL_SUPP:
printSkipped(nodeId, "can't bind memory: hwloc_topology_get_support() failed");
break;
case MEMBIND_FAIL_NODE:
printSkipped(nodeId, "can't bind memory: hwloc_get_numanode_obj_by_os_index() failed");
break;
case MEMBIND_FAIL_BIND:
printSkipped(nodeId, "can't bind memory: Cpu::info()->membind() failed");
break;
}
return; return;
} }