]> Cypherpunks repositories - gostls13.git/commit
runtime: don't hold the heap lock while scavenging
authorMichael Anthony Knyszek <mknyszek@google.com>
Mon, 4 Oct 2021 20:36:49 +0000 (20:36 +0000)
committerMichael Knyszek <mknyszek@google.com>
Fri, 5 Nov 2021 17:46:27 +0000 (17:46 +0000)
commit4f543b59c5618abccf0e78a17a2aeb173c085a91
treeaf28e8f1c618d2a91624923ea5f24d625cb6d0d8
parent0bc98b3e9b3b6b55489bb9ffed54377e678eba28
runtime: don't hold the heap lock while scavenging

This change modifies the scavenger to no longer hold the heap lock while
actively scavenging pages. To achieve this, the change also:
* Reverses the locking behavior of the (*pageAlloc).scavenge API, to
  only acquire the heap lock when necessary.
* Introduces a new lock on the scavenger-related fields in a pageAlloc
  so that access to those fields doesn't require the heap lock. There
  are a few places in the scavenge path, notably reservation, that
  requires synchronization. The heap lock is far too heavy handed for
  this case.
* Changes the scavenger to marks pages that are actively being scavenged
  as allocated, and "frees" them back to the page allocator the usual
  way.
* Lifts the heap-growth scavenging code out of mheap.grow, where the
  heap lock is held, and into allocSpan, just after the lock is
  released. Releasing the lock during mheap.grow is not feasible if we
  want to ensure that allocation always makes progress (post-growth,
  another allocator could come in and take all that space, forcing the
  goroutine that just grew the heap to do so again).

This change means that the scavenger now must do more work for each
scavenge, but it is also now much more scalable. Although in theory it's
not great by always taking the locked paths in the page allocator, it
takes advantage of some properties of the allocator:
* Most of the time, the scavenger will be working with one page at a
  time. The page allocator's locked path is optimized for this case.
* On the allocation path, it doesn't need to do the find operation at
  all; it can go straight to setting bits for the range and updating the
  summary structure.

Change-Id: Ie941d5e7c05dcc96476795c63fef74bcafc2a0f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/353974
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/runtime/export_test.go
src/runtime/lockrank.go
src/runtime/mgcscavenge.go
src/runtime/mgcscavenge_test.go
src/runtime/mheap.go
src/runtime/mpagealloc.go