diff options
-rw-r--r-- | doc/godebug.md | 13 | ||||
-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 |
4 files changed, 30 insertions, 0 deletions
diff --git a/doc/godebug.md b/doc/godebug.md index d26555503e..4b71e4d469 100644 --- a/doc/godebug.md +++ b/doc/godebug.md @@ -134,6 +134,19 @@ The default is tlsmaxrsasize=8192, limiting RSA to 8192-bit keys. To avoid denial of service attacks, this setting and default was backported to Go 1.19.13, Go 1.20.8, and Go 1.21.1. +Go 1.22 changed how the runtime interacts with transparent huge pages on Linux. +In particular, a common default Linux kernel configuration can result in +significant memory overheads, and Go 1.22 no longer works around this default. +To work around this issue without adjusting kernel settings, transparent huge +pages can be disabled for Go memory with the +[`disablethp` setting](/pkg/runtime#hdr-Environment_Variable). +This behavior was backported to Go 1.21.1, but the setting is only available +starting with Go 1.21.6. +This setting may be removed in a future release, and users impacted by this issue +should adjust their Linux configuration according to the recommendations in the +[GC guide](/doc/gc-guide#Linux_transparent_huge_pages), or switch to a Linux +distribution that disables transparent huge pages altogether. + ### Go 1.21 Go 1.21 made it a run-time error to call `panic` with a nil interface value, diff --git a/src/runtime/extern.go b/src/runtime/extern.go index 26dcf0bd52..de4a0ca2da 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 92a7e021ee..7174c63af3 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 @@ -342,6 +343,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}, |