mirror of
https://github.com/golang/go
synced 2024-11-24 09:30:07 -07:00
runtime: add harddecommit GODEBUG flag
This change adds a new debug flag that makes the runtime map pages PROT_NONE in sysUnused on Linux, in addition to the usual madvise calls. This behavior mimics the behavior of decommit on Windows, and is helpful in debugging the scavenger. sysUsed is also updated to re-map the pages as PROT_READ|PROT_WRITE, mimicing Windows' explicit commit behavior. Change-Id: Iaac5fcd0e6920bd1d0e753dd4e7f0c0b128fe842 Reviewed-on: https://go-review.googlesource.com/c/go/+/356612 Trust: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
4f543b59c5
commit
f063e0da28
@ -78,6 +78,11 @@ It is a comma-separated list of name=val pairs setting these named variables:
|
||||
If the line ends with "(forced)", this GC was forced by a
|
||||
runtime.GC() call.
|
||||
|
||||
harddecommit: setting harddecommit=1 causes memory that is returned to the OS to
|
||||
also have protections removed on it. This is the only mode of operation on Windows,
|
||||
but is helpful in debugging scavenger-related issues on other platforms. Currently,
|
||||
only supported on Linux.
|
||||
|
||||
inittrace: setting inittrace=1 causes the runtime to emit a single line to standard
|
||||
error for each package with init work, summarizing the execution time and memory
|
||||
allocation. No information is printed for inits executed as part of plugin loading
|
||||
|
@ -114,9 +114,29 @@ func sysUnused(v unsafe.Pointer, n uintptr) {
|
||||
atomic.Store(&adviseUnused, _MADV_DONTNEED)
|
||||
madvise(v, n, _MADV_DONTNEED)
|
||||
}
|
||||
|
||||
if debug.harddecommit > 0 {
|
||||
p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
|
||||
if p != v || err != 0 {
|
||||
throw("runtime: cannot disable permissions in address space")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sysUsed(v unsafe.Pointer, n uintptr) {
|
||||
if debug.harddecommit > 0 {
|
||||
p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
|
||||
if err == _ENOMEM {
|
||||
throw("runtime: out of memory")
|
||||
}
|
||||
if p != v || err != 0 {
|
||||
throw("runtime: cannot remap pages in address space")
|
||||
}
|
||||
return
|
||||
|
||||
// Don't do the sysHugePage optimization in hard decommit mode.
|
||||
// We're breaking up pages everywhere, there's no point.
|
||||
}
|
||||
// Partially undo the NOHUGEPAGE marks from sysUnused
|
||||
// for whole huge pages between v and v+n. This may
|
||||
// leave huge pages off at the end points v and v+n
|
||||
|
@ -315,6 +315,7 @@ var debug struct {
|
||||
schedtrace int32
|
||||
tracebackancestors int32
|
||||
asyncpreemptoff int32
|
||||
harddecommit int32
|
||||
|
||||
// debug.malloc is used as a combined debug check
|
||||
// in the malloc function and should be set
|
||||
@ -344,6 +345,7 @@ var dbgvars = []dbgVar{
|
||||
{"tracebackancestors", &debug.tracebackancestors},
|
||||
{"asyncpreemptoff", &debug.asyncpreemptoff},
|
||||
{"inittrace", &debug.inittrace},
|
||||
{"harddecommit", &debug.harddecommit},
|
||||
}
|
||||
|
||||
func parsedebugvars() {
|
||||
|
Loading…
Reference in New Issue
Block a user