8145000: TestOptionsWithRanges.java failure for XX:+UseNUMA -XX:+UseNUMAInterleaving -XX:NUMAInterleaveGranularity=65536
authorsangheki
Tue, 05 Jan 2016 10:41:56 -0800
changeset 35462 a1bed49c67a8
parent 35461 1068dcb8d315
child 35464 35f4f3d2812b
8145000: TestOptionsWithRanges.java failure for XX:+UseNUMA -XX:+UseNUMAInterleaving -XX:NUMAInterleaveGranularity=65536 Summary: Add protect_pages_individually() to protect memory per chunk on Windows Reviewed-by: jwilhelm, tbenson
hotspot/src/os/windows/vm/os_windows.cpp
hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Tue Jan 05 10:41:56 2016 -0800
@@ -3318,6 +3318,35 @@
   return os::uncommit_memory(addr, size);
 }
 
+static bool protect_pages_individually(char* addr, size_t bytes, unsigned int p, DWORD *old_status) {
+  uint count = 0;
+  bool ret = false;
+  size_t bytes_remaining = bytes;
+  char * next_protect_addr = addr;
+
+  // Use VirtualQuery() to get the chunk size.
+  while (bytes_remaining) {
+    MEMORY_BASIC_INFORMATION alloc_info;
+    if (VirtualQuery(next_protect_addr, &alloc_info, sizeof(alloc_info)) == 0) {
+      return false;
+    }
+
+    size_t bytes_to_protect = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
+    // We used different API at allocate_pages_individually() based on UseNUMAInterleaving,
+    // but we don't distinguish here as both cases are protected by same API.
+    ret = VirtualProtect(next_protect_addr, bytes_to_protect, p, old_status) != 0;
+    warning("Failed protecting pages individually for chunk #%u", count);
+    if (!ret) {
+      return false;
+    }
+
+    bytes_remaining -= bytes_to_protect;
+    next_protect_addr += bytes_to_protect;
+    count++;
+  }
+  return ret;
+}
+
 // Set protections specified
 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
                         bool is_committed) {
@@ -3345,7 +3374,25 @@
   // Pages in the region become guard pages. Any attempt to access a guard page
   // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
   // the guard page status. Guard pages thus act as a one-time access alarm.
-  return VirtualProtect(addr, bytes, p, &old_status) != 0;
+  bool ret;
+  if (UseNUMAInterleaving) {
+    // If UseNUMAInterleaving is enabled, the pages may have been allocated a chunk at a time,
+    // so we must protect the chunks individually.
+    ret = protect_pages_individually(addr, bytes, p, &old_status);
+  } else {
+    ret = VirtualProtect(addr, bytes, p, &old_status) != 0;
+  }
+#ifdef ASSERT
+  if (!ret) {
+    int err = os::get_last_error();
+    char buf[256];
+    size_t buf_len = os::lasterror(buf, sizeof(buf));
+    warning("INFO: os::protect_memory(" PTR_FORMAT ", " SIZE_FORMAT
+          ") failed; error='%s' (DOS error/errno=%d)", addr, bytes,
+          buf_len != 0 ? buf : "<no_error_string>", err);
+  }
+#endif
+  return ret;
 }
 
 bool os::guard_memory(char* addr, size_t bytes) {
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Tue Jan 05 10:41:56 2016 -0800
@@ -136,12 +136,6 @@
         excludeTestMaxRange("VMThreadStackSize");
 
         /*
-         * JDK-8145027
-         * Temporarily exclude as current range/constraint is not enough for some option combinations.
-         */
-        excludeTestRange("NUMAInterleaveGranularity");
-
-        /*
          * Remove parameters controlling the code cache. As these
          * parameters have implications on the physical memory
          * reserved by the VM, setting them to large values may hang