<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?&nbsp;&nbsp; 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">&lt;david.holmes@oracle.com&gt;</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">&lt;bengt.rutisson@oracle.com&gt;</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:
&gt;
&gt; Hi David,
&gt;
&gt; Updated webrev:
&gt; <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>
&gt;
&gt; I moved the alignment of "size" back into ReservedSpace::initialize()
&gt; since we actually store the size in an instance variable (_size), so I
&gt; think it is a bit risky to just do the align_up in
&gt; os::reserve_memory_aligned(). We probably want the instance variables
&gt; _size and _alignment in ReservedSpace to be consistent.
&gt;
&gt; I added an assert in os::reserve_memory_aligned() to verify that the
&gt; size is correctly aligned. I also added the assert you suggested to
&gt; check that alignment is page size aligned.
&gt;
&gt; Bengt
&gt;
&gt; On 12/13/12 11:50 AM, David Holmes wrote:
&gt;&gt; On 13/12/2012 8:37 PM, Bengt Rutisson wrote:
&gt;&gt;&gt;
&gt;&gt;&gt; Hi again,
&gt;&gt;&gt;
&gt;&gt;&gt; Updated webrev:
&gt;&gt;&gt; <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>
&gt;&gt;&gt;
&gt;&gt;&gt; I removed the comment and the alignment.
&gt;&gt;&gt;
&gt;&gt;&gt; But I did not add an assert just yet.
&gt;&gt;&gt;
&gt;&gt;&gt; At the top of ReservedSpace::initialize() we have this code:
&gt;&gt;&gt;
&gt;&gt;&gt; const size_t granularity = os::vm_allocation_granularity();
&gt;&gt;&gt; assert((size &amp; (granularity - 1)) == 0,
&gt;&gt;&gt; "size not aligned to os::vm_allocation_granularity()");
&gt;&gt;&gt; assert((alignment &amp; (granularity - 1)) == 0,
&gt;&gt;&gt; "alignment not aligned to os::vm_allocation_granularity()");
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; Where os::vm_allocation_granularity() is implemented as page size on all
&gt;&gt;&gt; platforms except Windows. There we look it up from the Windows API. I
&gt;&gt;&gt; assume that is a page size too, but since the Windows code in our patch
&gt;&gt;&gt; does not unmap based on the alignment it should be safe either way.
&gt;&gt;&gt;
&gt;&gt;&gt; Is this assert enough or would you like me to add an assert closer to
&gt;&gt;&gt; the code block were I did the changes?
&gt;&gt;
&gt;&gt; As this is a separate method now I think an assert in the method
&gt;&gt; itself would not go astray.
&gt;&gt;
&gt;&gt; David
&gt;&gt; -----
&gt;&gt;
&gt;&gt;&gt; Thanks,
&gt;&gt;&gt; Bengt
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; On 12/13/12 11:02 AM, Bengt Rutisson wrote:
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; Hi David,
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; Thanks for looking at this!
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; On 12/13/12 8:33 AM, David Holmes wrote:
&gt;&gt;&gt;&gt;&gt; Hi Bengt,
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; This has to be one of the absolute best review requests I've ever
&gt;&gt;&gt;&gt;&gt; read :) Thank you.
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; Wow! Thanks! :)
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; Just a couple of queries.
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; os_posix.cpp:
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; Love the diagram :)
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; It was Mikael's way of making sure we got it right.
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; I'm assuming that "alignment" has to be &gt;= the underlying page size,
&gt;&gt;&gt;&gt;&gt; and in fact must be a multiple of the underlying page size ? (As I
&gt;&gt;&gt;&gt;&gt; assume you can only unmap whole numbers of pages). If so does that
&gt;&gt;&gt;&gt;&gt; need to be checked somewhere?
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; Good point. I'll add an assert to check that.
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; In virtualSpace.cpp:
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; // Reserve size large enough to do manual alignment and
&gt;&gt;&gt;&gt;&gt; // increase size to a multiple of the desired alignment
&gt;&gt;&gt;&gt;&gt; size = align_size_up(size, alignment);
&gt;&gt;&gt;&gt;&gt; ! base = os::reserve_memory_aligned(size, alignment);
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; The comment doesn't seem necessary now, and the align_size_up seems
&gt;&gt;&gt;&gt;&gt; redundant.
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; You are right. I'll remove the comment and the alignment.
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt; Thanks,
&gt;&gt;&gt;&gt; Bengt
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; Thanks,
&gt;&gt;&gt;&gt;&gt; David
&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt; On 13/12/2012 4:42 PM, Bengt Rutisson wrote:
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; Hi all,
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; Could I have a couple of reviews for this change?
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; <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>
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; This is for a bug originally reported by the Coherence team:
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; 7173959 : Jvm crashed during coherence exabus (tmb) testing
&gt;&gt;&gt;&gt;&gt;&gt; <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>
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; The original analysis and proposed fix was done by Mikael Gerdin
&gt;&gt;&gt;&gt;&gt;&gt; and me
&gt;&gt;&gt;&gt;&gt;&gt; together. I'll handle the webrev and push since Mikael is on vacation
&gt;&gt;&gt;&gt;&gt;&gt; starting today. But Mikael did a great job tracking down this very
&gt;&gt;&gt;&gt;&gt;&gt; difficult bug, so he should have a large part of the credit for this
&gt;&gt;&gt;&gt;&gt;&gt; bug
&gt;&gt;&gt;&gt;&gt;&gt; fix,
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; Description from the CR:
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; The reason that we crash is due to how we re-map memory when we
&gt;&gt;&gt;&gt;&gt;&gt; want to
&gt;&gt;&gt;&gt;&gt;&gt; align it for large pages in ReservedSpace::initialize().
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; Here is what happens:
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; The reservation of memory is split up to a few steps. When we want a
&gt;&gt;&gt;&gt;&gt;&gt; chunk of memory with large pages we first just reserve some memory
&gt;&gt;&gt;&gt;&gt;&gt; large
&gt;&gt;&gt;&gt;&gt;&gt; enough for what we need. Then we realize that we want large pages,
&gt;&gt;&gt;&gt;&gt;&gt; so we
&gt;&gt;&gt;&gt;&gt;&gt; want to re-map the reserved memory to use large pages. But since this
&gt;&gt;&gt;&gt;&gt;&gt; requires that we have a large-page-aligned memory chunk we may
&gt;&gt;&gt;&gt;&gt;&gt; have to
&gt;&gt;&gt;&gt;&gt;&gt; fix the recently reserved memory chunk up a bit.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; We do this in ReservedSpace::initialize() by first releasing the
&gt;&gt;&gt;&gt;&gt;&gt; memory
&gt;&gt;&gt;&gt;&gt;&gt; we just reserved. Then requesting more memory than we actually
&gt;&gt;&gt;&gt;&gt;&gt; need to
&gt;&gt;&gt;&gt;&gt;&gt; make sure that we have enough space to do manual large page
&gt;&gt;&gt;&gt;&gt;&gt; alignment.
&gt;&gt;&gt;&gt;&gt;&gt; After we have gotten this memory we figure out a nicely aligned start
&gt;&gt;&gt;&gt;&gt;&gt; address. We then release the memory again and then reserve just
&gt;&gt;&gt;&gt;&gt;&gt; enough
&gt;&gt;&gt;&gt;&gt;&gt; memory but using the aligned start address as a fixed address to make
&gt;&gt;&gt;&gt;&gt;&gt; sure that we get the memory we wanted in an aligned way.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; This is done in a loop to make sure that we eventually get some
&gt;&gt;&gt;&gt;&gt;&gt; memory.
&gt;&gt;&gt;&gt;&gt;&gt; The interesting code looks like this:
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; do {
&gt;&gt;&gt;&gt;&gt;&gt; char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
&gt;&gt;&gt;&gt;&gt;&gt; if (extra_base == NULL) return;
&gt;&gt;&gt;&gt;&gt;&gt; // Do manual alignement
&gt;&gt;&gt;&gt;&gt;&gt; base = (char*) align_size_up((uintptr_t) extra_base, alignment);
&gt;&gt;&gt;&gt;&gt;&gt; assert(base &gt;= extra_base, "just checking");
&gt;&gt;&gt;&gt;&gt;&gt; // Re-reserve the region at the aligned base address.
&gt;&gt;&gt;&gt;&gt;&gt; os::release_memory(extra_base, extra_size); // (1)
&gt;&gt;&gt;&gt;&gt;&gt; base = os::reserve_memory(size, base); // (2)
&gt;&gt;&gt;&gt;&gt;&gt; } while (base == NULL);
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; There is a race here between releasing the memory in (1) and
&gt;&gt;&gt;&gt;&gt;&gt; re-reserving it in (2). But the loop is supposed to handle this race.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; The problem is that on posix platforms you can remap the same memory
&gt;&gt;&gt;&gt;&gt;&gt; area several times. The call in (2) will use mmap with MAP_FIXED.
&gt;&gt;&gt;&gt;&gt;&gt; This
&gt;&gt;&gt;&gt;&gt;&gt; means that the OS will think that you know exactly what you are
&gt;&gt;&gt;&gt;&gt;&gt; doing.
&gt;&gt;&gt;&gt;&gt;&gt; So, if part of the memory has been mapped already by the process it
&gt;&gt;&gt;&gt;&gt;&gt; will
&gt;&gt;&gt;&gt;&gt;&gt; just go ahead and reuse that memory.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; This means that if we are having multiple threads that do mmap. We
&gt;&gt;&gt;&gt;&gt;&gt; can
&gt;&gt;&gt;&gt;&gt;&gt; end up with a situation where we release our mapping in (1). Then
&gt;&gt;&gt;&gt;&gt;&gt; another thread comes in and maps part of the memory that we used to
&gt;&gt;&gt;&gt;&gt;&gt; have. Then we remap over that memory again in (2) with MAP_FIXED.
&gt;&gt;&gt;&gt;&gt;&gt; Now we
&gt;&gt;&gt;&gt;&gt;&gt; have a situation where two threads in our process have mapped the
&gt;&gt;&gt;&gt;&gt;&gt; same
&gt;&gt;&gt;&gt;&gt;&gt; memory. If both threads try to use it or if one of the threads unmap
&gt;&gt;&gt;&gt;&gt;&gt; part or all of the memory we will crash.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; On posix it is possible to unmap any part of a mapped chunk. So, our
&gt;&gt;&gt;&gt;&gt;&gt; proposed solution to the race described above is to not unmap all
&gt;&gt;&gt;&gt;&gt;&gt; memory
&gt;&gt;&gt;&gt;&gt;&gt; in (1) but rather just unmap the section at the start and at the
&gt;&gt;&gt;&gt;&gt;&gt; end of
&gt;&gt;&gt;&gt;&gt;&gt; the chunk that we mapped to get alignment. This also removes the need
&gt;&gt;&gt;&gt;&gt;&gt; for the loop.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; However, on Windows you can only unmap _all_ of the memory that you
&gt;&gt;&gt;&gt;&gt;&gt; have
&gt;&gt;&gt;&gt;&gt;&gt; mapped. On the other hand Windows also will not allow you to map over
&gt;&gt;&gt;&gt;&gt;&gt; other mappings, so the original code is actually safe. If we keep
&gt;&gt;&gt;&gt;&gt;&gt; the loop.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; So, our solution is to treat this differently on Windows and posix
&gt;&gt;&gt;&gt;&gt;&gt; platforms.
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt;
&gt;&gt;&gt;&gt;&gt;&gt; Thanks,
&gt;&gt;&gt;&gt;&gt;&gt; Bengt
&gt;&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;
</pre>
          <br>
          <br>
        </div>
        <br>
      </blockquote>
    </blockquote>
    <br>
  </body>
</html>