diff options
| author | Michael Anthony Knyszek <mknyszek@google.com> | 2023-12-05 17:31:34 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-12-05 20:14:52 +0000 |
| commit | c915215af65897cc9cffed75630cbfbc6b2462cc (patch) | |
| tree | a0d6bbc7cd410d74fc12b2c06bfa58d0e4a24c16 /src/runtime | |
| parent | 3d2645f337091e8cd3f6f0979716fa6cd124ffaa (diff) | |
| download | go-c915215af65897cc9cffed75630cbfbc6b2462cc.tar.xz | |
runtime: add the disablethp GODEBUG setting
Go 1.21.1 and Go 1.22 have ceased working around an issue with Linux
kernel defaults for transparent huge pages that can result in excessive
memory overheads. (https://bugzilla.kernel.org/show_bug.cgi?id=93111)
Many Linux distributions disable huge pages altogether these days, so
this problem isn't quite as far-reaching as it used to be. Also, the
problem only affects Go programs with very particular memory usage
patterns.
That being said, because the runtime used to actively deal with this
problem (but with some unpredictable behavior), it's preventing users
that don't have a lot of control over their execution environment from
upgrading to Go beyond Go 1.20.
This change adds a GODEBUG to smooth over the transition. The GODEBUG
setting disables transparent huge pages for all heap memory on Linux,
which is much more predictable than restoring the old behavior.
Fixes #64332.
Change-Id: I73b1894337f0f0b1a5a17b90da1221e118e0b145
Reviewed-on: https://go-review.googlesource.com/c/go/+/547475
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/extern.go | 7 | ||||
| -rw-r--r-- | src/runtime/mem_linux.go | 8 | ||||
| -rw-r--r-- | src/runtime/runtime1.go | 2 |
3 files changed, 17 insertions, 0 deletions
diff --git a/src/runtime/extern.go b/src/runtime/extern.go index d199720b9b..03050df766 100644 --- a/src/runtime/extern.go +++ b/src/runtime/extern.go @@ -55,6 +55,13 @@ It is a comma-separated list of name=val pairs setting these named variables: cgocheck mode can be enabled using GOEXPERIMENT (which requires a rebuild), see https://pkg.go.dev/internal/goexperiment for details. + disablethp: setting disablethp=1 on Linux disables transparent huge pages for the heap. + It has no effect on other platforms. disablethp is meant for compatibility with versions + of Go before 1.21, which stopped working around a Linux kernel default that can result + in significant memory overuse. See https://go.dev/issue/64332. This setting will be + removed in a future release, so operators should tweak their Linux configuration to suit + their needs before then. See https://go.dev/doc/gc-guide#Linux_transparent_huge_pages. + dontfreezetheworld: by default, the start of a fatal panic or throw "freezes the world", preempting all threads to stop all running goroutines, which makes it possible to traceback all goroutines, and diff --git a/src/runtime/mem_linux.go b/src/runtime/mem_linux.go index c9823d3011..d63c38c209 100644 --- a/src/runtime/mem_linux.go +++ b/src/runtime/mem_linux.go @@ -170,4 +170,12 @@ func sysMapOS(v unsafe.Pointer, n uintptr) { print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n") throw("runtime: cannot map pages in arena address space") } + + // Disable huge pages if the GODEBUG for it is set. + // + // Note that there are a few sysHugePage calls that can override this, but + // they're all for GC metadata. + if debug.disablethp != 0 { + sysNoHugePageOS(v, n) + } } diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go index 877d94eef2..087d5ebce7 100644 --- a/src/runtime/runtime1.go +++ b/src/runtime/runtime1.go @@ -309,6 +309,7 @@ type dbgVar struct { var debug struct { cgocheck int32 clobberfree int32 + disablethp int32 dontfreezetheworld int32 efence int32 gccheckmark int32 @@ -344,6 +345,7 @@ var dbgvars = []*dbgVar{ {name: "allocfreetrace", value: &debug.allocfreetrace}, {name: "clobberfree", value: &debug.clobberfree}, {name: "cgocheck", value: &debug.cgocheck}, + {name: "disablethp", value: &debug.disablethp}, {name: "dontfreezetheworld", value: &debug.dontfreezetheworld}, {name: "efence", value: &debug.efence}, {name: "gccheckmark", value: &debug.gccheckmark}, |
