Don't use MREMAP_DONTUNMAP on host when kernel < 5.13 am: 605774b259 am: c5474f5195 am: dbe43f8b60
Original change: https://android-review.googlesource.com/c/platform/art/+/2182518
Change-Id: Idbc31e8e12d61d8335f770ee1caad7429e8b81ec
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc
index 0701ceb..8240711 100644
--- a/runtime/gc/collector/mark_compact.cc
+++ b/runtime/gc/collector/mark_compact.cc
@@ -60,18 +60,20 @@
namespace art {
+// We require MREMAP_DONTUNMAP functionality in mremap syscall, which was
+// introduced in 5.13 kernel version. Check for that on host. Checking
+// on target is not required as MREMAP_DONTUNMAP and userfaultfd were enabled
+// together.
+#ifdef ART_TARGET
+static const bool gHaveMremapDontunmap = true;
+#else
+static const bool gHaveMremapDontunmap = IsKernelVersionAtLeast(5, 13);
+#endif
+
#ifndef ART_FORCE_USE_READ_BARRIER
static bool ShouldUseUserfaultfd() {
#if !defined(__linux__)
return false;
-#elif !defined(ART_TARGET)
- // We require MREMAP_DONTUNMAP functionality in mremap syscall, which was
- // introduced in 5.13 kernel version. Check for that on host. Not required
- // checking on target as MREMAP_DONTUNMAP and userfaultfd were enabled
- // together.
- if (!IsKernelVersionAtLeast(5, 13)) {
- return false;
- }
#endif
int fd = syscall(__NR_userfaultfd, O_CLOEXEC | UFFD_USER_MODE_ONLY);
#ifndef ART_TARGET
@@ -1757,15 +1759,23 @@
// mremap.
size_t size = bump_pointer_space_->Capacity();
uint8_t* begin = bump_pointer_space_->Begin();
- void* ret = mremap(begin,
- size,
- size,
- MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_DONTUNMAP,
- from_space_begin_);
+ int flags = MREMAP_MAYMOVE | MREMAP_FIXED;
+ if (gHaveMremapDontunmap) {
+ flags |= MREMAP_DONTUNMAP;
+ }
+
+ void* ret = mremap(begin, size, size, flags, from_space_begin_);
CHECK_EQ(ret, static_cast<void*>(from_space_begin_))
- << "mremap to move pages from moving space to from-space failed: " << strerror(errno)
- << ". moving-space-addr=" << reinterpret_cast<void*>(begin)
- << " size=" << size;
+ << "mremap to move pages from moving space to from-space failed: " << strerror(errno)
+ << ". moving-space-addr=" << reinterpret_cast<void*>(begin)
+ << " size=" << size;
+
+ // Without MREMAP_DONTUNMAP the source mapping is unmapped by mremap. So mmap
+ // the moving space again.
+ if (!gHaveMremapDontunmap) {
+ ret = mmap(begin, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
+ CHECK_EQ(ret, static_cast<void*>(begin)) << "mmap for moving space failed: " << strerror(errno);
+ }
DCHECK_EQ(mprotect(from_space_begin_, size, PROT_READ), 0)
<< "mprotect failed: " << strerror(errno);