<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix"><br>
Hi Zhengyu,<br>
<br>
Thanks for looking at this!<br>
<br>
On 12/14/12 3:59 PM, Zhengyu Gu wrote:<br>
</div>
<blockquote cite="mid:50CB3EC2.2090901@oracle.com" type="cite">
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
Looks good to me.<br>
<br>
From NMT perspective, as long as os::xxxx_memory methods are used,
you don't need to add NMT hooks, but you do have to be careful
about tagging the memory pointers returned by os::reserve_memory()
methods. But for VirtualSpace and ReservedSpace, etc. utility
classes, they are tagged by their callers.<br>
</blockquote>
<br>
Thanks for verifying this.<br>
<br>
Bengt<br>
<br>
<blockquote cite="mid:50CB3EC2.2090901@oracle.com" type="cite"> <br>
Thanks,<br>
<br>
-Zhengyu<br>
<br>
On 12/14/2012 7:44 AM, Coleen Phillimore wrote:
<blockquote cite="mid:50CB1F33.60605@oracle.com" type="cite">
<meta http-equiv="content-type" content="text/html;
charset=ISO-8859-1">
<br>
Does NMT track this? Will this mess up NMT?<br>
Coleen<br>
<div class="moz-forward-container"><br>
<br>
-------- Original Message --------
<table class="moz-email-headers-table" border="0"
cellpadding="0" cellspacing="0">
<tbody>
<tr>
<th align="RIGHT" nowrap="nowrap" valign="BASELINE">Subject:
</th>
<td>Re: Request for review (s): 7173959 : Jvm crashed
during coherence exabus (tmb) testing</td>
</tr>
<tr>
<th align="RIGHT" nowrap="nowrap" valign="BASELINE">Date:
</th>
<td>Fri, 14 Dec 2012 10:38:34 +1000</td>
</tr>
<tr>
<th align="RIGHT" nowrap="nowrap" valign="BASELINE">From:
</th>
<td>David Holmes <a moz-do-not-send="true"
class="moz-txt-link-rfc2396E"
href="mailto:david.holmes@oracle.com"><david.holmes@oracle.com></a></td>
</tr>
<tr>
<th align="RIGHT" nowrap="nowrap" valign="BASELINE">Organization:
</th>
<td>Oracle Corporation</td>
</tr>
<tr>
<th align="RIGHT" nowrap="nowrap" valign="BASELINE">To:
</th>
<td>Bengt Rutisson <a moz-do-not-send="true"
class="moz-txt-link-rfc2396E"
href="mailto:bengt.rutisson@oracle.com"><bengt.rutisson@oracle.com></a></td>
</tr>
<tr>
<th align="RIGHT" nowrap="nowrap" valign="BASELINE">CC:
</th>
<td><a moz-do-not-send="true"
class="moz-txt-link-abbreviated"
href="mailto:hotspot-runtime-dev@openjdk.java.net">hotspot-runtime-dev@openjdk.java.net</a></td>
</tr>
</tbody>
</table>
<br>
<br>
<pre>Hi Bengt,
That all sounds good to me.
With regard to potential overflow perhaps a simple check that extra_size
does not overflow? If that is true and extra_base is not null then I
think all the other calculations must be valid.
Thanks,
David
On 13/12/2012 10:58 PM, Bengt Rutisson wrote:
>
> Hi David,
>
> Updated webrev:
> <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/%7Ebrutisso/7173959/webrev.02/">http://cr.openjdk.java.net/~brutisso/7173959/webrev.02/</a>
>
> I moved the alignment of "size" back into ReservedSpace::initialize()
> since we actually store the size in an instance variable (_size), so I
> think it is a bit risky to just do the align_up in
> os::reserve_memory_aligned(). We probably want the instance variables
> _size and _alignment in ReservedSpace to be consistent.
>
> I added an assert in os::reserve_memory_aligned() to verify that the
> size is correctly aligned. I also added the assert you suggested to
> check that alignment is page size aligned.
>
> Bengt
>
> On 12/13/12 11:50 AM, David Holmes wrote:
>> On 13/12/2012 8:37 PM, Bengt Rutisson wrote:
>>>
>>> Hi again,
>>>
>>> Updated webrev:
>>> <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/%7Ebrutisso/7173959/webrev.01/">http://cr.openjdk.java.net/~brutisso/7173959/webrev.01/</a>
>>>
>>> I removed the comment and the alignment.
>>>
>>> But I did not add an assert just yet.
>>>
>>> At the top of ReservedSpace::initialize() we have this code:
>>>
>>> const size_t granularity = os::vm_allocation_granularity();
>>> assert((size & (granularity - 1)) == 0,
>>> "size not aligned to os::vm_allocation_granularity()");
>>> assert((alignment & (granularity - 1)) == 0,
>>> "alignment not aligned to os::vm_allocation_granularity()");
>>>
>>>
>>> Where os::vm_allocation_granularity() is implemented as page size on all
>>> platforms except Windows. There we look it up from the Windows API. I
>>> assume that is a page size too, but since the Windows code in our patch
>>> does not unmap based on the alignment it should be safe either way.
>>>
>>> Is this assert enough or would you like me to add an assert closer to
>>> the code block were I did the changes?
>>
>> As this is a separate method now I think an assert in the method
>> itself would not go astray.
>>
>> David
>> -----
>>
>>> Thanks,
>>> Bengt
>>>
>>>
>>> On 12/13/12 11:02 AM, Bengt Rutisson wrote:
>>>>
>>>> Hi David,
>>>>
>>>> Thanks for looking at this!
>>>>
>>>> On 12/13/12 8:33 AM, David Holmes wrote:
>>>>> Hi Bengt,
>>>>>
>>>>> This has to be one of the absolute best review requests I've ever
>>>>> read :) Thank you.
>>>>
>>>> Wow! Thanks! :)
>>>>
>>>>>
>>>>> Just a couple of queries.
>>>>>
>>>>> os_posix.cpp:
>>>>>
>>>>> Love the diagram :)
>>>>
>>>> It was Mikael's way of making sure we got it right.
>>>>
>>>>> I'm assuming that "alignment" has to be >= the underlying page size,
>>>>> and in fact must be a multiple of the underlying page size ? (As I
>>>>> assume you can only unmap whole numbers of pages). If so does that
>>>>> need to be checked somewhere?
>>>>
>>>> Good point. I'll add an assert to check that.
>>>>
>>>>> In virtualSpace.cpp:
>>>>>
>>>>> // Reserve size large enough to do manual alignment and
>>>>> // increase size to a multiple of the desired alignment
>>>>> size = align_size_up(size, alignment);
>>>>> ! base = os::reserve_memory_aligned(size, alignment);
>>>>>
>>>>> The comment doesn't seem necessary now, and the align_size_up seems
>>>>> redundant.
>>>>
>>>> You are right. I'll remove the comment and the alignment.
>>>>
>>>> Thanks,
>>>> Bengt
>>>>
>>>>>
>>>>> Thanks,
>>>>> David
>>>>>
>>>>> On 13/12/2012 4:42 PM, Bengt Rutisson wrote:
>>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> Could I have a couple of reviews for this change?
>>>>>>
>>>>>> <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/%7Ebrutisso/7173959/webrev.00/">http://cr.openjdk.java.net/~brutisso/7173959/webrev.00/</a>
>>>>>>
>>>>>> This is for a bug originally reported by the Coherence team:
>>>>>>
>>>>>> 7173959 : Jvm crashed during coherence exabus (tmb) testing
>>>>>> <a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7173959">http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7173959</a>
>>>>>>
>>>>>> The original analysis and proposed fix was done by Mikael Gerdin
>>>>>> and me
>>>>>> together. I'll handle the webrev and push since Mikael is on vacation
>>>>>> starting today. But Mikael did a great job tracking down this very
>>>>>> difficult bug, so he should have a large part of the credit for this
>>>>>> bug
>>>>>> fix,
>>>>>>
>>>>>> Description from the CR:
>>>>>>
>>>>>> The reason that we crash is due to how we re-map memory when we
>>>>>> want to
>>>>>> align it for large pages in ReservedSpace::initialize().
>>>>>>
>>>>>> Here is what happens:
>>>>>>
>>>>>> The reservation of memory is split up to a few steps. When we want a
>>>>>> chunk of memory with large pages we first just reserve some memory
>>>>>> large
>>>>>> enough for what we need. Then we realize that we want large pages,
>>>>>> so we
>>>>>> want to re-map the reserved memory to use large pages. But since this
>>>>>> requires that we have a large-page-aligned memory chunk we may
>>>>>> have to
>>>>>> fix the recently reserved memory chunk up a bit.
>>>>>>
>>>>>> We do this in ReservedSpace::initialize() by first releasing the
>>>>>> memory
>>>>>> we just reserved. Then requesting more memory than we actually
>>>>>> need to
>>>>>> make sure that we have enough space to do manual large page
>>>>>> alignment.
>>>>>> After we have gotten this memory we figure out a nicely aligned start
>>>>>> address. We then release the memory again and then reserve just
>>>>>> enough
>>>>>> memory but using the aligned start address as a fixed address to make
>>>>>> sure that we get the memory we wanted in an aligned way.
>>>>>>
>>>>>> This is done in a loop to make sure that we eventually get some
>>>>>> memory.
>>>>>> The interesting code looks like this:
>>>>>>
>>>>>> do {
>>>>>> char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
>>>>>> if (extra_base == NULL) return;
>>>>>> // Do manual alignement
>>>>>> base = (char*) align_size_up((uintptr_t) extra_base, alignment);
>>>>>> assert(base >= extra_base, "just checking");
>>>>>> // Re-reserve the region at the aligned base address.
>>>>>> os::release_memory(extra_base, extra_size); // (1)
>>>>>> base = os::reserve_memory(size, base); // (2)
>>>>>> } while (base == NULL);
>>>>>>
>>>>>>
>>>>>> There is a race here between releasing the memory in (1) and
>>>>>> re-reserving it in (2). But the loop is supposed to handle this race.
>>>>>>
>>>>>> The problem is that on posix platforms you can remap the same memory
>>>>>> area several times. The call in (2) will use mmap with MAP_FIXED.
>>>>>> This
>>>>>> means that the OS will think that you know exactly what you are
>>>>>> doing.
>>>>>> So, if part of the memory has been mapped already by the process it
>>>>>> will
>>>>>> just go ahead and reuse that memory.
>>>>>>
>>>>>> This means that if we are having multiple threads that do mmap. We
>>>>>> can
>>>>>> end up with a situation where we release our mapping in (1). Then
>>>>>> another thread comes in and maps part of the memory that we used to
>>>>>> have. Then we remap over that memory again in (2) with MAP_FIXED.
>>>>>> Now we
>>>>>> have a situation where two threads in our process have mapped the
>>>>>> same
>>>>>> memory. If both threads try to use it or if one of the threads unmap
>>>>>> part or all of the memory we will crash.
>>>>>>
>>>>>> On posix it is possible to unmap any part of a mapped chunk. So, our
>>>>>> proposed solution to the race described above is to not unmap all
>>>>>> memory
>>>>>> in (1) but rather just unmap the section at the start and at the
>>>>>> end of
>>>>>> the chunk that we mapped to get alignment. This also removes the need
>>>>>> for the loop.
>>>>>>
>>>>>> However, on Windows you can only unmap _all_ of the memory that you
>>>>>> have
>>>>>> mapped. On the other hand Windows also will not allow you to map over
>>>>>> other mappings, so the original code is actually safe. If we keep
>>>>>> the loop.
>>>>>>
>>>>>> So, our solution is to treat this differently on Windows and posix
>>>>>> platforms.
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Bengt
>>>>
>>>
>
</pre>
<br>
<br>
</div>
<br>
</blockquote>
</blockquote>
<br>
</body>
</html>