Reland "Depend only on userfaultfd's SIGBUS feature to use it"
This reverts commit fab50833f1787848002bb96a6033f08a8c5212d3.
Reason for revert: Fix the features requested in uffd API ioctl.
Bug: 160737021
Bug: 291694105
Bug: 292449808
Test: On a host kernel < 5.14 run ART_USE_READ_BARRIER=false
art/test/testrunner/testunner.py --host
Change-Id: I41be8f1d080043558ac7125980fef599dadeb6d5
diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc
index 05ca803..85e6a5f 100644
--- a/runtime/gc/collector/mark_compact.cc
+++ b/runtime/gc/collector/mark_compact.cc
@@ -116,17 +116,13 @@
static constexpr uint64_t kUffdFeaturesForMinorFault =
UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_MINOR_SHMEM;
static constexpr uint64_t kUffdFeaturesForSigbus = UFFD_FEATURE_SIGBUS;
+
// We consider SIGBUS feature necessary to enable this GC as it's superior than
// threading-based implementation for janks. However, since we have the latter
// already implemented, for testing purposes, we allow choosing either of the
// two at boot time in the constructor below.
-// Note that having minor-fault feature implies having SIGBUS feature as the
-// latter was introduced earlier than the former. In other words, having
-// minor-fault feature implies having SIGBUS. We still want minor-fault to be
-// available for making jit-code-cache updation concurrent, which uses shmem.
-static constexpr uint64_t kUffdFeaturesRequired =
- kUffdFeaturesForMinorFault | kUffdFeaturesForSigbus;
-
+// We may want minor-fault in future to be available for making jit-code-cache
+// updation concurrent, which uses shmem.
bool KernelSupportsUffd() {
#ifdef __linux__
if (gHaveMremapDontunmap) {
@@ -144,8 +140,8 @@
CHECK_EQ(ioctl(fd, UFFDIO_API, &api), 0) << "ioctl_userfaultfd : API:" << strerror(errno);
gUffdFeatures = api.features;
close(fd);
- // Allow this GC to be used only if minor-fault and sigbus feature is available.
- return (api.features & kUffdFeaturesRequired) == kUffdFeaturesRequired;
+ // Minimum we need is sigbus feature for using userfaultfd.
+ return (api.features & kUffdFeaturesForSigbus) == kUffdFeaturesForSigbus;
}
}
#endif
@@ -344,8 +340,21 @@
} else {
DCHECK(IsValidFd(uffd_));
// Initialize uffd with the features which are required and available.
- struct uffdio_api api = {.api = UFFD_API, .features = gUffdFeatures, .ioctls = 0};
- api.features &= use_uffd_sigbus_ ? kUffdFeaturesRequired : kUffdFeaturesForMinorFault;
+ // Using private anonymous mapping in threading mode is the default,
+ // for which we don't need to ask for any features. Note: this mode
+ // is not used in production.
+ struct uffdio_api api = {.api = UFFD_API, .features = 0, .ioctls = 0};
+ if (use_uffd_sigbus_) {
+ // We should add SIGBUS feature only if we plan on using it as
+ // requesting it here will mean threading mode will not work.
+ CHECK_EQ(gUffdFeatures & kUffdFeaturesForSigbus, kUffdFeaturesForSigbus);
+ api.features |= kUffdFeaturesForSigbus;
+ }
+ if (uffd_minor_fault_supported_) {
+ // NOTE: This option is currently disabled.
+ CHECK_EQ(gUffdFeatures & kUffdFeaturesForMinorFault, kUffdFeaturesForMinorFault);
+ api.features |= kUffdFeaturesForMinorFault;
+ }
CHECK_EQ(ioctl(uffd_, UFFDIO_API, &api), 0)
<< "ioctl_userfaultfd: API: " << strerror(errno);
}
@@ -366,7 +375,7 @@
static bool IsSigbusFeatureAvailable() {
MarkCompact::GetUffdAndMinorFault();
- return gUffdFeatures & UFFD_FEATURE_SIGBUS;
+ return (gUffdFeatures & kUffdFeaturesForSigbus) == kUffdFeaturesForSigbus;
}
MarkCompact::MarkCompact(Heap* heap)