Skip to content

Commit

Permalink
issue: Check for resident hugepages to avoid SIGBUS
Browse files Browse the repository at this point in the history
In a containerized environment mmap() beyond the hugepages limit can be
successful, but a further memory access triggers SIGBUS and terminates
the process. Check that all the allocated hugepages are resident with
mincore() to avoid the SIGBUS issue.

Signed-off-by: Dmytro Podgornyi <[email protected]>
  • Loading branch information
pasis committed Jul 29, 2024
1 parent dd775c9 commit 69ec7ad
Showing 1 changed file with 28 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/core/util/hugepage_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,34 @@ void *hugepage_mgr::alloc_hugepages_helper(size_t &size, size_t hugepage)
ptr = nullptr;
__log_info_dbg("mmap failed (errno=%d), skipping hugepage %zu kB", errno, hugepage / 1024U);
} else {
size = actual_size;
// Check whether all the pages are resident. In a container, allocation beyond the limit can
// be successful and lead to SIGBUS on an access.
const size_t pages_nr = actual_size / hugepage;
size_t resident_nr = 0;
char *page_ptr = reinterpret_cast<char *>(ptr);
int rc = 0;

for (size_t i = 0; rc == 0 && i < pages_nr; ++i) {
unsigned char vec;
rc = mincore(page_ptr, 1, &vec);
resident_nr += rc == 0 ? (vec & 1U) : 0;
page_ptr += hugepage;
}

if (rc != 0 || resident_nr != pages_nr) {
munmap(ptr, actual_size);
ptr = nullptr;
if (rc < 0) {
__log_info_dbg("mincore() failed to verify hugepages (errno=%d)", errno);
} else if (resident_nr != pages_nr) {
__log_info_dbg("Not all hugepages are resident (allocated=%zu resident=%zu)",
pages_nr, resident_nr);
}
__log_info_dbg("Cannot use hugepages, skipping hugepage %zu kB", hugepage / 1024U);
} else {
// Success.
size = actual_size;
}
}
return ptr;
}
Expand Down

0 comments on commit 69ec7ad

Please sign in to comment.