Commit 9113678d authored by Banit Agrawal's avatar Banit Agrawal Committed by Facebook Github Bot

Never decay the huge pages in JEMalloc

Summary: This diff disables the purging of huge pages and hence they will never be freed and will be counted towards the RSS of the process. This was done to ensure that we don't block on madvise call to get the huge pages and increase memory pressure on the system.

Reviewed By: gdankel

Differential Revision: D18607196

fbshipit-source-id: 79e483a715290fdfbdd1963433ec3918561a0e0e
parent 6a47d8fb
......@@ -69,7 +69,7 @@ static void print_error(int err, const char* msg) {
class HugePageArena {
public:
int init(int nr_pages, const JemallocHugePageAllocator::Options& options);
int init(int nr_pages);
void* reserve(size_t size, size_t alignment);
bool addressInArena(void* address) {
......@@ -181,9 +181,7 @@ void* HugePageArena::allocHook(
return res;
}
int HugePageArena::init(
int nr_pages,
const JemallocHugePageAllocator::Options& options) {
int HugePageArena::init(int nr_pages) {
DCHECK(start_ == 0);
DCHECK(usingJEMalloc());
......@@ -246,10 +244,9 @@ int HugePageArena::init(
return 0;
}
if (options.noDecay) {
// Set decay time to 0, which will cause jemalloc to free memory
// back to kernel immediately.
ssize_t decay_ms = 0;
// Set dirty decay and muzzy decay time to -1, which will cause jemalloc
// to never free memory to kernel.
ssize_t decay_ms = -1;
std::ostringstream dirty_decay_key;
dirty_decay_key << "arena." << arenaIndex_ << ".dirty_decay_ms";
if (auto ret = mallctl(
......@@ -258,9 +255,19 @@ int HugePageArena::init(
nullptr,
&decay_ms,
sizeof(decay_ms))) {
print_error(ret, "Unable to set decay time");
print_error(ret, "Unable to set dirty decay time");
return 0;
}
std::ostringstream muzzy_decay_key;
muzzy_decay_key << "arena." << arenaIndex_ << ".muzzy_decay_ms";
if (auto ret = mallctl(
muzzy_decay_key.str().c_str(),
nullptr,
nullptr,
&decay_ms,
sizeof(decay_ms))) {
print_error(ret, "Unable to set muzzy decay time");
return 0;
}
start_ = freePtr_ = map_pages(nr_pages);
......@@ -287,14 +294,14 @@ void* HugePageArena::reserve(size_t size, size_t alignment) {
int JemallocHugePageAllocator::flags_{0};
bool JemallocHugePageAllocator::init(int nr_pages, const Options& options) {
bool JemallocHugePageAllocator::init(int nr_pages) {
if (!usingJEMalloc()) {
LOG(ERROR) << "Not linked with jemalloc?";
hugePagesSupported = false;
}
if (hugePagesSupported) {
if (flags_ == 0) {
flags_ = arena.init(nr_pages, options);
flags_ = arena.init(nr_pages);
} else {
LOG(WARNING) << "Already initialized";
}
......
......@@ -50,27 +50,17 @@ namespace folly {
*
* If binary isn't linked with jemalloc, the logic falls back to malloc / free.
*
* Note that the madvise call does not guarantee huge pages, it is best effort.
* Please note that as per kernel contract, page faults on an madvised region
* will block, so we pre-allocate all the huge pages by touching the pages.
* So, please only allocate as much you need as this will never be freed
* during the lifetime of the application. If we run out of the free huge pages,
* then huge page allocator falls back to the 4K regular pages.
*
* 1GB Huge Pages are not supported at this point.
*/
class JemallocHugePageAllocator {
public:
struct Options {
// Set decay time to 0, which will cause jemalloc to free memory
// back to kernel immediately. It can still be reclaimed later if
// the kernel hasn't reused it for something else.
// This is primarily useful for preventing RSS regressions, but
// can cause the number of available pages to shrink over time
// as the likelihood they get reused by the kernel is increased.
bool noDecay = false;
};
static bool init(int nr_pages) {
return init(nr_pages, Options());
}
static bool init(int nr_pages, const Options& options);
static bool init(int nr_pages);
static void* allocate(size_t size) {
// If uninitialized, flags_ will be 0 and the mallocx behavior
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment