Skip to content

Commit 55ed8cf

Browse files
committed
memory: warn about locking limits and enable running without by defining DATADIST_NO_MLOCK variable
1 parent 9cf83fb commit 55ed8cf

2 files changed

Lines changed: 38 additions & 10 deletions

File tree

src/TfBuilder/TfBuilderDevice.cxx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ void TfBuilderDevice::PreRun()
128128

129129
bool TfBuilderDevice::start()
130130
{
131+
mTfBuilder = std::make_unique<TimeFrameBuilder>(MemI(), mTfBufferSize, 512 << 20 /* config */, dplEnabled());
132+
131133
// start all gRPC clients
132134
while (!mRpc->start(mTfBufferSize)) {
133135
// try to reach the scheduler unless we should exit
@@ -142,8 +144,6 @@ bool TfBuilderDevice::start()
142144
// we reached the scheduler instance, initialize everything else
143145
mRunning = true;
144146

145-
mTfBuilder = std::make_unique<TimeFrameBuilder>(MemI(), mTfBufferSize, 512 << 20 /* config */, dplEnabled());
146-
147147
if (!mStandalone && dplEnabled()) {
148148
auto& lOutputChan = GetChannel(getDplChannelName(), 0);
149149
mTfDplAdapter = std::make_unique<StfToDplAdapter>(lOutputChan);
@@ -180,10 +180,6 @@ void TfBuilderDevice::stop()
180180
mTfDplAdapter->stop();
181181
}
182182

183-
if (mTfBuilder) {
184-
mTfBuilder->stop();
185-
}
186-
187183
mRunning = false;
188184
DDDLOG("TfBuilderDevice::stop(): mRunning is false.");
189185

@@ -217,6 +213,11 @@ void TfBuilderDevice::stop()
217213

218214
mDiscoveryConfig.reset();
219215

216+
// memory resource is last to destruct
217+
if (mTfBuilder) {
218+
mTfBuilder->stop();
219+
}
220+
220221
DDDLOG("TfBuilderDevice() stopped... ");
221222
}
222223

src/common/include/MemoryUtils.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#include <cstdlib>
3636
#include <unistd.h>
3737

38+
#if defined(__linux__)
39+
#include <sys/resource.h>
40+
#endif
41+
3842
class DataHeader;
3943
class FairMQUnmanagedRegion;
4044

@@ -43,6 +47,7 @@ namespace o2
4347
namespace DataDistribution
4448
{
4549

50+
static constexpr const char *ENV_NOLOCK = "DATADIST_NO_MLOCK";
4651
static constexpr const char *ENV_SHM_PATH = "DATADIST_SHM_PATH";
4752
static constexpr const char *ENV_SHM_DELAY = "DATADIST_SHM_DELAY";
4853

@@ -65,16 +70,38 @@ class RegionAllocatorResource
6570
int lMapFlags = 0;
6671
std::string lSegmentRoot = "";
6772

68-
// don't reserve swap space and try to lock the region
69-
#if defined(MAP_NORESERVE) && defined(MAP_LOCKED)
70-
lMapFlags = MAP_NORESERVE | MAP_LOCKED;
73+
// don't reserve swap space
74+
#if defined(MAP_NORESERVE)
75+
lMapFlags |= MAP_NORESERVE;
76+
#endif
77+
78+
// and try to lock the memory
79+
#if defined(MAP_LOCKED) && defined(__linux__)
80+
{
81+
struct rlimit lMyLimits;
82+
getrlimit(RLIMIT_MEMLOCK, &lMyLimits);
83+
84+
if (lMyLimits.rlim_cur >= pSize) {
85+
lMapFlags |= MAP_LOCKED;
86+
} else {
87+
if (std::getenv(ENV_NOLOCK)) {
88+
WDDLOG("MemoryResource: Memory locking disabled via {} env variable. Not suitable for production.",
89+
ENV_NOLOCK);
90+
} else {
91+
EDDLOG("MemoryResource: Failed to lock the memory region. Increase your memory lock limits (ulimit -l).");
92+
EDDLOG("MemoryResource: To run without memory locking define {} env variable. Not suitable for production.",
93+
ENV_NOLOCK);
94+
throw std::bad_alloc();
95+
}
96+
}
97+
}
7198
#endif
99+
72100
// populate the mapping
73101
#if defined(MAP_POPULATE)
74102
lMapFlags |= MAP_POPULATE;
75103
#endif
76104

77-
78105
// try to use different file mapping (hugetlbfs)
79106
const auto lHugetlbfsPath = std::getenv(ENV_SHM_PATH);
80107
if (lHugetlbfsPath) {

0 commit comments

Comments
 (0)