This commit is contained in:
commit
b4c93b7ff6
97 changed files with 6697 additions and 6013 deletions
|
@ -74,6 +74,7 @@ bool xmrig::Rx::init(const Job &job, const RxConfig &config, const CpuConfig &cp
|
|||
|
||||
if (!osInitialized) {
|
||||
msrInit(config);
|
||||
setupMainLoopExceptionFrame();
|
||||
osInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -131,4 +132,8 @@ void xmrig::Rx::msrDestroy()
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef XMRIG_FIX_RYZEN
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -57,9 +57,14 @@ public:
|
|||
static void destroy();
|
||||
static void init(IRxListener *listener);
|
||||
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
static void setMainLoopBounds(const std::pair<const void*, const void*>& bounds);
|
||||
# endif
|
||||
|
||||
private:
|
||||
static void msrInit(const RxConfig &config);
|
||||
static void msrDestroy();
|
||||
static void setupMainLoopExceptionFrame();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -57,9 +57,6 @@ const RandomX_ConfigurationBase *xmrig::RxAlgo::base(Algorithm::Id algorithm)
|
|||
case Algorithm::RX_SFX:
|
||||
return &RandomX_SafexConfig;
|
||||
|
||||
case Algorithm::RX_V:
|
||||
return &RandomX_VConfig;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
static inline Algorithm::Id id(Algorithm::Id algorithm)
|
||||
{
|
||||
if (algorithm == Algorithm::RX_SFX || algorithm == Algorithm::RX_V) {
|
||||
if (algorithm == Algorithm::RX_SFX) {
|
||||
return Algorithm::RX_0;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,13 +48,11 @@ public:
|
|||
XMRIG_DISABLE_COPY_MOVE(RxBasicStoragePrivate)
|
||||
|
||||
inline RxBasicStoragePrivate() = default;
|
||||
inline ~RxBasicStoragePrivate()
|
||||
{
|
||||
delete m_dataset;
|
||||
}
|
||||
inline ~RxBasicStoragePrivate() { deleteDataset(); }
|
||||
|
||||
inline bool isReady(const Job &job) const { return m_ready && m_seed == job; }
|
||||
inline RxDataset *dataset() const { return m_dataset; }
|
||||
inline void deleteDataset() { delete m_dataset; m_dataset = nullptr; }
|
||||
|
||||
|
||||
inline void setSeed(const RxSeed &seed)
|
||||
|
@ -69,12 +67,22 @@ public:
|
|||
}
|
||||
|
||||
|
||||
inline void createDataset(bool hugePages, bool oneGbPages, RxConfig::Mode mode)
|
||||
inline bool createDataset(bool hugePages, bool oneGbPages, RxConfig::Mode mode)
|
||||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
m_dataset = new RxDataset(hugePages, oneGbPages, true, mode, 0);
|
||||
if (!m_dataset->cache()->get()) {
|
||||
deleteDataset();
|
||||
|
||||
LOG_INFO("%s" RED_BOLD("failed to allocate RandomX memory") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
printAllocStatus(ts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,11 +90,11 @@ public:
|
|||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
m_dataset->init(m_seed.data(), threads, priority);
|
||||
m_ready = m_dataset->init(m_seed.data(), threads, priority);
|
||||
|
||||
LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
m_ready = true;
|
||||
if (m_ready) {
|
||||
LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,6 +144,12 @@ xmrig::RxBasicStorage::~RxBasicStorage()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::RxBasicStorage::isAllocated() const
|
||||
{
|
||||
return d_ptr->dataset() && d_ptr->dataset()->cache() && d_ptr->dataset()->cache()->get();
|
||||
}
|
||||
|
||||
|
||||
xmrig::HugePagesInfo xmrig::RxBasicStorage::hugePages() const
|
||||
{
|
||||
if (!d_ptr->dataset()) {
|
||||
|
@ -160,8 +174,8 @@ void xmrig::RxBasicStorage::init(const RxSeed &seed, uint32_t threads, bool huge
|
|||
{
|
||||
d_ptr->setSeed(seed);
|
||||
|
||||
if (!d_ptr->dataset()) {
|
||||
d_ptr->createDataset(hugePages, oneGbPages, mode);
|
||||
if (!d_ptr->dataset() && !d_ptr->createDataset(hugePages, oneGbPages, mode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->initDataset(threads, priority);
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
~RxBasicStorage() override;
|
||||
|
||||
protected:
|
||||
bool isAllocated() const override;
|
||||
HugePagesInfo hugePages() const override;
|
||||
RxDataset *dataset(const Job &job, uint32_t nodeId) const override;
|
||||
void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) override;
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
#include "crypto/randomx/randomx.h"
|
||||
|
||||
|
||||
static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch");
|
||||
static_assert(RANDOMX_FLAG_LARGE_PAGES == 1, "RANDOMX_FLAG_LARGE_PAGES flag mismatch");
|
||||
|
||||
static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch");
|
||||
|
||||
|
||||
xmrig::RxCache::RxCache(bool hugePages, uint32_t nodeId)
|
||||
|
@ -64,9 +62,14 @@ bool xmrig::RxCache::init(const Buffer &seed)
|
|||
}
|
||||
|
||||
m_seed = seed;
|
||||
randomx_init_cache(m_cache, m_seed.data(), m_seed.size());
|
||||
|
||||
return true;
|
||||
if (m_cache) {
|
||||
randomx_init_cache(m_cache, m_seed.data(), m_seed.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,6 +81,10 @@ xmrig::HugePagesInfo xmrig::RxCache::hugePages() const
|
|||
|
||||
void xmrig::RxCache::create(uint8_t *memory)
|
||||
{
|
||||
if (!memory) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_cache = randomx_create_cache(RANDOMX_FLAG_JIT, memory);
|
||||
|
||||
if (!m_cache) {
|
||||
|
|
|
@ -65,7 +65,7 @@ constexpr size_t kMsrArraySize = 4;
|
|||
static const std::array<MsrItems, kMsrArraySize> msrPresets = {
|
||||
MsrItems(),
|
||||
MsrItems{{ 0xC0011020, 0x0 }, { 0xC0011021, 0x40, ~0x20ULL }, { 0xC0011022, 0x510000 }, { 0xC001102b, 0x1808cc16 }},
|
||||
MsrItems{{ 0x1a4, 0x6 }},
|
||||
MsrItems{{ 0x1a4, 0xf }},
|
||||
MsrItems()
|
||||
};
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ xmrig::RxDataset::~RxDataset()
|
|||
|
||||
bool xmrig::RxDataset::init(const Buffer &seed, uint32_t numThreads, int priority)
|
||||
{
|
||||
if (!m_cache) {
|
||||
if (!m_cache || !m_cache->get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
inline void createDatasets(bool hugePages, bool oneGbPages)
|
||||
inline bool createDatasets(bool hugePages, bool oneGbPages)
|
||||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
|
@ -133,6 +133,10 @@ public:
|
|||
if (isCacheRequired()) {
|
||||
std::thread thread(allocateCache, this, m_nodeset.front(), hugePages);
|
||||
thread.join();
|
||||
|
||||
if (!m_cache) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_datasets.empty()) {
|
||||
|
@ -149,6 +153,8 @@ public:
|
|||
}
|
||||
|
||||
m_allocated = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,6 +243,13 @@ private:
|
|||
bindToNUMANode(nodeId);
|
||||
|
||||
auto cache = new RxCache(hugePages, nodeId);
|
||||
if (!cache->get()) {
|
||||
delete cache;
|
||||
|
||||
LOG_INFO("%s" RED_BOLD("failed to allocate RandomX memory") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
d_ptr->m_cache = cache;
|
||||
|
@ -336,6 +349,12 @@ xmrig::RxNUMAStorage::~RxNUMAStorage()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::RxNUMAStorage::isAllocated() const
|
||||
{
|
||||
return d_ptr->isAllocated();
|
||||
}
|
||||
|
||||
|
||||
xmrig::HugePagesInfo xmrig::RxNUMAStorage::hugePages() const
|
||||
{
|
||||
if (!d_ptr->isAllocated()) {
|
||||
|
@ -360,8 +379,8 @@ void xmrig::RxNUMAStorage::init(const RxSeed &seed, uint32_t threads, bool hugeP
|
|||
{
|
||||
d_ptr->setSeed(seed);
|
||||
|
||||
if (!d_ptr->isAllocated()) {
|
||||
d_ptr->createDatasets(hugePages, oneGbPages);
|
||||
if (!d_ptr->isAllocated() && !d_ptr->createDatasets(hugePages, oneGbPages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->initDatasets(threads, priority);
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
~RxNUMAStorage() override;
|
||||
|
||||
protected:
|
||||
bool isAllocated() const override;
|
||||
HugePagesInfo hugePages() const override;
|
||||
RxDataset *dataset(const Job &job, uint32_t nodeId) const override;
|
||||
void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) override;
|
||||
|
|
|
@ -126,7 +126,7 @@ void xmrig::RxQueue::enqueue(const RxSeed &seed, const std::vector<uint32_t> &no
|
|||
|
||||
bool xmrig::RxQueue::isReadyUnsafe(const Job &job) const
|
||||
{
|
||||
return m_storage != nullptr && m_state == STATE_IDLE && m_seed == job;
|
||||
return m_storage != nullptr && m_storage->isAllocated() && m_state == STATE_IDLE && m_seed == job;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -178,6 +180,33 @@ static bool wrmsr(const MsrItems &preset, bool save)
|
|||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
ucontext_t *ucp = (ucontext_t*) ucontext;
|
||||
|
||||
LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
|
||||
void* p = reinterpret_cast<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -208,3 +237,15 @@ void xmrig::Rx::msrDestroy()
|
|||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
struct sigaction act = {};
|
||||
act.sa_sigaction = MainLoopHandler;
|
||||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
sigaction(SIGSEGV, &act, nullptr);
|
||||
sigaction(SIGILL, &act, nullptr);
|
||||
# endif
|
||||
}
|
||||
|
|
|
@ -303,6 +303,43 @@ static bool wrmsr(const MsrItems &preset, bool save)
|
|||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
static LONG WINAPI MainLoopHandler(_EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {
|
||||
const char* accessType;
|
||||
switch (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) {
|
||||
case 0: accessType = "read"; break;
|
||||
case 1: accessType = "write"; break;
|
||||
case 8: accessType = "DEP violation"; break;
|
||||
default: accessType = "unknown"; break;
|
||||
}
|
||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Access violation at 0x%p: %s at address 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionAddress, accessType, ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
|
||||
}
|
||||
else {
|
||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
void* p = reinterpret_cast<void*>(ExceptionInfo->ContextRecord->Rip);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -333,3 +370,11 @@ void xmrig::Rx::msrDestroy()
|
|||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
AddVectoredExceptionHandler(1, MainLoopHandler);
|
||||
# endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue