File tree Expand file tree Collapse file tree 3 files changed +40
-0
lines changed
Expand file tree Collapse file tree 3 files changed +40
-0
lines changed Original file line number Diff line number Diff line change @@ -453,6 +453,9 @@ namespace cryptonote
453453 {
454454 start_time = std::time (nullptr );
455455
456+ // Necessary for FCMP++ sync on Linux platforms, especially with limited memory
457+ rct::limitMaxMemArenas ();
458+
456459 const bool regtest = command_line::get_arg (vm, arg_regtest_on);
457460 if (test_options != NULL || regtest)
458461 {
Original file line number Diff line number Diff line change 4444#include " device/device.hpp"
4545#include " serialization/crypto.h"
4646
47+ #if defined(__GLIBC__)
48+ #include < malloc.h>
49+ #endif
50+
4751using namespace crypto ;
4852using namespace std ;
4953
@@ -1747,4 +1751,26 @@ namespace rct {
17471751 }
17481752 return true ;
17491753 }
1754+
1755+ void limitMaxMemArenas ()
1756+ {
1757+ #ifdef M_ARENA_MAX
1758+ tools::threadpool &tpool = tools::threadpool::getInstanceForCompute ();
1759+ const std::size_t n_threads = std::max<std::size_t >(1 , tpool.get_max_concurrency ());
1760+
1761+ // See mallopt and M_ARENA_MAX at: https://man7.org/linux/man-pages/man3/mallopt.3.html
1762+ int r = mallopt (M_ARENA_MAX, n_threads);
1763+ if (r == 1 )
1764+ {
1765+ MDEBUG (" Set max arenas to " << n_threads);
1766+ return ;
1767+ }
1768+
1769+ MWARNING (" Failed to set max arenas, the system may use more memory than expected during sync." );
1770+ #else
1771+ MDEBUG (" System does not have mallopt and M_ARENA_MAX setting. This setting is crucial for some Linux platforms to"
1772+ << " avoid OOM's when batch verifying FCMP++ txs. If we see OOM's in the future when batch verifying on a non-"
1773+ << " Linux platform, then check the system allocator behavior and see if it has a setting similar to mallopt" );
1774+ #endif
1775+ }
17501776}
Original file line number Diff line number Diff line change @@ -147,6 +147,17 @@ namespace rct {
147147
148148 // Split into batches and verify each batch in parallel
149149 bool batchVerifyFcmpPpProofs (std::vector<fcmp_pp::FcmpPpVerifyInput> &&fcmp_pp_verify_inputs);
150+
151+ // The default libc allocator on most Linux systems may cache allocated memory for reuse.
152+ // As a result, verifying many large batches of FCMP++ proofs in multithreaded contexts
153+ // can end up using a lot of memory that does not get released back to the OS, even
154+ // though memory is already freed.
155+ // This function uses the mallopt syscall to limit the max number of "arenas" the system
156+ // may use, setting it to the number of threads the system has. This way there won't
157+ // be more memory allocated and kept around than expected in a potentially unbounded
158+ // number of arenas.
159+ // More on this here: https://gotplt.org/posts/malloc-per-thread-arenas-in-glibc.html
160+ void limitMaxMemArenas ();
150161}
151162#endif /* RCTSIGS_H */
152163
You can’t perform that action at this time.
0 commit comments