diff options
author | Michael Anthony Knyszek <mknyszek@google.com> | 2023-11-10 21:23:38 +0000 |
---|---|---|
committer | Gopher Robot <gobot@golang.org> | 2023-11-28 18:46:34 +0000 |
commit | 3684d19c20d73baba3ea2ae7e86d002465a24508 (patch) | |
tree | 95bc1fbc1abd1a93221ba82c9e2615ad25d9b944 | |
parent | 9e43850a3298a9b8b1162ba0033d4c53f8637571 (diff) | |
download | go-3684d19c20d73baba3ea2ae7e86d002465a24508.tar.gz go-3684d19c20d73baba3ea2ae7e86d002465a24508.zip |
[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 5f08b4479930af266d4a84c1533b320ed75edba7)
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>
-rw-r--r-- | src/runtime/malloc.go | 4 | ||||
-rw-r--r-- | src/runtime/mgc.go | 4 | ||||
-rw-r--r-- | src/runtime/mpagealloc.go | 4 |
3 files changed, 11 insertions, 1 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 44479cc2be..b2026ad0dc 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -853,6 +853,10 @@ retry: // // The heap lock must not be held over this operation, since it will briefly acquire // the heap lock. +// +// Must be called on the system stack because it acquires the heap lock. +// +//go:systemstack func (h *mheap) enableMetadataHugePages() { // Enable huge pages for page structure. h.pages.enableChunkHugePages() diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index de5ae0ae00..a12dbfe9df 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -1186,7 +1186,9 @@ func gcMarkTermination() { // Enable huge pages on some metadata if we cross a heap threshold. if gcController.heapGoal() > minHeapForMetadataHugePages { - mheap_.enableMetadataHugePages() + systemstack(func() { + mheap_.enableMetadataHugePages() + }) } semrelease(&worldsema) diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go index 3e789ab85c..2861fa93eb 100644 --- a/src/runtime/mpagealloc.go +++ b/src/runtime/mpagealloc.go @@ -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 be called on the system stack because it acquires the heap lock. +// +//go:systemstack func (p *pageAlloc) enableChunkHugePages() { // Grab the heap lock to turn on huge pages for new chunks and clone the current // heap address space ranges. |