mirror of https://github.com/golang/go.git
[release-branch.go1.21] runtime: call enableMetadataHugePages and its callees on the systemstack
These functions acquire the heap lock. If they're not called on the
systemstack, a stack growth could cause a self-deadlock since stack
growth may allocate memory from the page heap.
This has been a problem for a while. If this is what's plaguing the
ppc64 port right now, it's very surprising (and probably just
coincidental) that it's showing up now.
For #64050.
For #64062.
For #64067.
Fixes #64073.
Change-Id: I2b95dc134d17be63b9fe8f7a3370fe5b5438682f
Reviewed-on: https://go-review.googlesource.com/c/go/+/541635
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Paul Murphy <murp@ibm.com>
(cherry picked from commit 5f08b44799)
Reviewed-on: https://go-review.googlesource.com/c/go/+/541955
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
parent
9e43850a32
commit
3684d19c20
|
|
@ -853,6 +853,10 @@ retry:
|
||||||
//
|
//
|
||||||
// The heap lock must not be held over this operation, since it will briefly acquire
|
// The heap lock must not be held over this operation, since it will briefly acquire
|
||||||
// the heap lock.
|
// the heap lock.
|
||||||
|
//
|
||||||
|
// Must be called on the system stack because it acquires the heap lock.
|
||||||
|
//
|
||||||
|
//go:systemstack
|
||||||
func (h *mheap) enableMetadataHugePages() {
|
func (h *mheap) enableMetadataHugePages() {
|
||||||
// Enable huge pages for page structure.
|
// Enable huge pages for page structure.
|
||||||
h.pages.enableChunkHugePages()
|
h.pages.enableChunkHugePages()
|
||||||
|
|
|
||||||
|
|
@ -1186,7 +1186,9 @@ func gcMarkTermination() {
|
||||||
|
|
||||||
// Enable huge pages on some metadata if we cross a heap threshold.
|
// Enable huge pages on some metadata if we cross a heap threshold.
|
||||||
if gcController.heapGoal() > minHeapForMetadataHugePages {
|
if gcController.heapGoal() > minHeapForMetadataHugePages {
|
||||||
mheap_.enableMetadataHugePages()
|
systemstack(func() {
|
||||||
|
mheap_.enableMetadataHugePages()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
semrelease(&worldsema)
|
semrelease(&worldsema)
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,10 @@ func (p *pageAlloc) grow(base, size uintptr) {
|
||||||
//
|
//
|
||||||
// The heap lock must not be held over this operation, since it will briefly acquire
|
// The heap lock must not be held over this operation, since it will briefly acquire
|
||||||
// the heap lock.
|
// the heap lock.
|
||||||
|
//
|
||||||
|
// Must be called on the system stack because it acquires the heap lock.
|
||||||
|
//
|
||||||
|
//go:systemstack
|
||||||
func (p *pageAlloc) enableChunkHugePages() {
|
func (p *pageAlloc) enableChunkHugePages() {
|
||||||
// Grab the heap lock to turn on huge pages for new chunks and clone the current
|
// Grab the heap lock to turn on huge pages for new chunks and clone the current
|
||||||
// heap address space ranges.
|
// heap address space ranges.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue