Request for approval: 6929067: Stack guard pages should be removed when thread is detached

David Holmes David.Holmes at oracle.com
Wed Aug 18 20:49:36 PDT 2010


Here's the prototype including the safety-check Coleen wanted.

diff -r f707b4c0c36f src/os/linux/vm/os_linux.cpp
--- a/src/os/linux/vm/os_linux.cpp
+++ b/src/os/linux/vm/os_linux.cpp
@@ -2628,10 +2628,12 @@ get_stack_bounds(uintptr_t *bottom, uint
  // where we're going to put our guard pages, truncate the mapping at
  // that point by munmap()ping it.  This ensures that when we later
  // munmap() the guard pages we don't leave a hole in the stack
-// mapping.
+// mapping. This only affects the main/initial thread, but guard
+// against future OS changes
  bool os::create_stack_guard_pages(char* addr, size_t size) {
    uintptr_t stack_extent, stack_base;
-  if (get_stack_bounds(&stack_extent, &stack_base)) {
+  if (NOT_DEBUG(os::Linux::is_initial_thread() &&) 
get_stack_bounds(&stack_extent, &stack_base)) {
+      assert(os::Linux::is_initial_thread(), "growable stack in 
non-initial thread");
      if (stack_extent < (uintptr_t)addr)
        ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
    }
@@ -2640,10 +2642,13 @@ bool os::create_stack_guard_pages(char*
  }

  // If this is a growable mapping, remove the guard pages entirely by
-// munmap()ping them.  If not, just call uncommit_memory().
+// munmap()ping them.  If not, just call uncommit_memory(). This only
+// affects the main/initial thread, but guard against future OS changes
  bool os::remove_stack_guard_pages(char* addr, size_t size) {
    uintptr_t stack_extent, stack_base;
-  if (get_stack_bounds(&stack_extent, &stack_base)) {
+  if (NOT_DEBUG(os::Linux::is_initial_thread() &&) 
get_stack_bounds(&stack_extent, &stack_base)) {
+      assert(os::Linux::is_initial_thread(), "growable stack in 
non-initial thread");
+
      return ::munmap(addr, size) == 0;
    }

We skip get_stack_bounds for all but the main thread in product mode; 
then in debug mode we always call get_stack_bounds but trigger an assert 
of we seem to find a growable stack that does not belong to the main thread.

This fixes our performance issue, but otherwise has not been fully tested.

David
-----


David Holmes said the following on 08/19/10 09:41:
> Andrew Haley said the following on 08/17/10 18:14:
>> On 08/16/2010 11:57 PM, David Holmes wrote:
>>> Andrew Haley said the following on 08/16/10 18:42:
>>>> On 08/16/2010 03:46 AM, David Holmes wrote:
>>>>> Looking further into this, isn't the only thread that can be 
>>>>> affected by
>>>>> this the main thread? So we could perform this only if
>>>>> os::is_initial_thread() returns true?
>>>> I suppose we could, yes.  I wonder if it'd be a latent bug to assume
>>>> that Java threads could never use growable mappings, though.  Doing
>>>> this makes the system a bit less robust.
>>> As I understand it neither LinuxThreads nor NPTL have used growable
>>> mappings for a very long time. Even if there were a reason to go back to
>>> this it would have to be done in a compatible way and so there would be
>>> time to "enhance" the VM to accommodate it.
>>
>> Oh, I'm sure there would.  The problem is that this bug is very
>> subtle, and if it came back again it would be just as hard to
>> diagnose.  If the change to use growable mappings were made upstream
>> on some platform, would we notice?
> 
> I would hope (and I know hopes can be dashed) that the upstream 
> maintainers would not make such a change silently.
> 
> Was there a regression test created for this bug? That would catch any 
> change.
> 
> David
> -----
> 
>>>> Do you really think that the cost of get_stack_bounds() is 
>>>> significant in
>>>> the context of terminating a thread?
>>> It can be. This has introduced a new bottleneck on the thread
>>> termination path and we're seeing that affect on certain systems (the
>>> details of which I can't go in to).
>>
>> Aha, so this is not just a theoretical concern.  Fair enough.  It
>> seems like I may have falsely assumed the work in the kernel to
>> terminate a thread would be greater than this.
>>
>> Andrew.


More information about the hotspot-dev mailing list