runtime: add the disablethp GODEBUG setting Signed-off-by: Vanient <xiadanni1@huawei.com> (cherry picked from commit cc5d48f4b7efbea6fda3cac36203412597a6d177)
130 lines
5.7 KiB
Diff
130 lines
5.7 KiB
Diff
From 8440c7cdaf2aa9e52fc63c731564e98fbcdbb806 Mon Sep 17 00:00:00 2001
|
|
From: Michael Anthony Knyszek <mknyszek@google.com>
|
|
Date: Tue, 5 Dec 2023 17:31:34 +0000
|
|
Subject: [PATCH 08/20] [release-branch.go1.21] runtime: add the disablethp
|
|
GODEBUG setting
|
|
|
|
Conflict:NA
|
|
Reference:https://go-review.googlesource.com/c/go/+/547475
|
|
|
|
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.
|
|
|
|
For #64332.
|
|
Fixes #64561.
|
|
|
|
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>
|
|
(cherry picked from commit c915215af65897cc9cffed75630cbfbc6b2462cc)
|
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/547636
|
|
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
|
|
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
|
|
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
|
|
---
|
|
doc/godebug.md | 13 +++++++++++++
|
|
src/runtime/extern.go | 7 +++++++
|
|
src/runtime/mem_linux.go | 8 ++++++++
|
|
src/runtime/runtime1.go | 2 ++
|
|
4 files changed, 30 insertions(+)
|
|
|
|
diff --git a/doc/godebug.md b/doc/godebug.md
|
|
index d26555503e05..4b71e4d46985 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 26dcf0bd52b2..de4a0ca2dade 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 c9823d301133..d63c38c209d8 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 92a7e021ee23..7174c63af354 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},
|
|
--
|
|
2.33.0
|
|
|