• Austin Clements's avatar
    [release-branch.go1.9] runtime: map bitmap and spans during heap initialization · 196492a2
    Austin Clements authored
    We lazily map the bitmap and spans areas as the heap grows. However,
    right now we're very slightly too lazy. Specifically, the following
    can happen on 32-bit:
    
    1. mallocinit fails to allocate any heap arena, so
       arena_used == arena_alloc == arena_end == bitmap.
    
    2. There's less than 256MB between the end of the bitmap mapping and
       the next mapping.
    
    3. On the first allocation, mheap.sysAlloc sees that there's not
       enough room in [arena_alloc, arena_end) because there's no room at
       all. It gets a 256MB mapping from somewhere *lower* in the address
       space than arena_used and sets arena_alloc and arena_end to this
       hole.
    
    4. Since the new arena_alloc is lower than arena_used, mheap.sysAlloc
       doesn't bother to call mheap.setArenaUsed, so we still don't have a
       bitmap mapping or a spans array mapping.
    
    5. mheap.grow, which called mheap.sysAlloc, attempts to fill in the
       spans array and crashes.
    
    Fix this by mapping the metadata regions for the initial arena_used
    when the heap is initialized, rather than trying to wait for an
    allocation. This maintains the intended invariant that the structures
    are always mapped for [arena_start, arena_used).
    
    Fixes #21044.
    
    Cherry-pick of CL 51714. Fixes #21234.
    
    Change-Id: I4422375a6e234b9f979d22135fc63ae3395946b0
    Reviewed-on: https://go-review.googlesource.com/52191
    
    
    Run-TryBot: Austin Clements <austin@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
    196492a2
mheap.go 51.2 KB