Skip to content

Commit d23774a

Browse files
committed
Implement NUMA binding support for PosixShmSegment
1 parent 19473e9 commit d23774a

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

cachelib/shm/PosixShmSegment.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <sys/mman.h>
2222
#include <sys/stat.h>
2323
#include <sys/types.h>
24+
#include <numa.h>
25+
#include <numaif.h>
2426

2527
#include "cachelib/common/Utils.h"
2628

@@ -176,13 +178,52 @@ void* PosixShmSegment::mapAddress(void* addr) const {
176178
util::throwSystemError(EINVAL, "Address already mapped");
177179
}
178180
XDCHECK(retAddr == addr || addr == nullptr);
181+
memBind(addr);
179182
return retAddr;
180183
}
181184

182185
void PosixShmSegment::unMap(void* addr) const {
183186
detail::munmapImpl(addr, getSize());
184187
}
185188

189+
static void forcePageAllocation(void* addr, size_t size, size_t pageSize) {
190+
for(volatile char* curAddr = (char*)addr; curAddr < (char*)addr+size; curAddr += pageSize) {
191+
*curAddr = *curAddr;
192+
}
193+
}
194+
195+
void PosixShmSegment::memBind(void* addr) const {
196+
if(opts_.memBindNumaNodes.empty()) return;
197+
198+
struct bitmask *oldNodeMask = numa_allocate_nodemask();
199+
int oldMode = 0;
200+
struct bitmask *nodesMask = numa_allocate_nodemask();
201+
auto guard = folly::makeGuard([&] { numa_bitmask_free(nodesMask); numa_bitmask_free(oldNodeMask); });
202+
203+
for(auto node : opts_.memBindNumaNodes) {
204+
numa_bitmask_setbit(nodesMask, node);
205+
}
206+
207+
// mbind() cannot be used because mmap was called with MAP_SHARED flag
208+
// But we can set memory policy for current thread and force page allcoation.
209+
// The following logic is used:
210+
// 1. Remember current memory policy for the current thread
211+
// 2. Set new memory policy as specifiec by config
212+
// 3. Force page allocation by touching every page in the segment
213+
// 4. Restore memory policy
214+
215+
// Remember current memory policy
216+
get_mempolicy(&oldMode, oldNodeMask->maskp, oldNodeMask->size, nullptr, 0);
217+
218+
// Set memory bindings
219+
set_mempolicy(MPOL_BIND, nodesMask->maskp, nodesMask->size);
220+
221+
forcePageAllocation(addr, getSize(), detail::getPageSize(opts_.pageSize));
222+
223+
// Restore memory policy for the thread
224+
set_mempolicy(oldMode, nodesMask->maskp, nodesMask->size);
225+
}
226+
186227
std::string PosixShmSegment::createKeyForName(
187228
const std::string& name) noexcept {
188229
// ensure that the slash is always there in the head. repetitive

cachelib/shm/PosixShmSegment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class PosixShmSegment : public ShmBase {
108108
void createReferenceMapping();
109109
void deleteReferenceMapping() const;
110110

111+
void memBind(void* addr) const;
112+
111113
// file descriptor associated with the shm. This has FD_CLOEXEC set
112114
// and once opened, we close this only on destruction of this object
113115
int fd_{kInvalidFD};

0 commit comments

Comments
 (0)