aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-07-21 18:38:05 -0400
committerDavid Chase <drchase@google.com>2021-07-22 17:01:15 +0000
commitfdb45acd1f062884c77ea6961fb638e004af1b8e (patch)
treee5e241b71592c0f592cb31087e3dc78b02c56d06
parent3e48c0381fd1beb78e993e940c3b46ca9898ce6d (diff)
downloadgo-fdb45acd1f062884c77ea6961fb638e004af1b8e.tar.gz
go-fdb45acd1f062884c77ea6961fb638e004af1b8e.zip
runtime: move mem profile sampling into m-acquired section
It was not safe to do mcache profiling updates outside the critical section, but we got lucky because the runtime was not preemptible. Adding chunked memory clearing (CL 270943) created preemption opportunities, which led to corruption of runtime data structures. Fixes #47304. Fixes #47302. Change-Id: I461615470d62328a83ccbac537fbdc6dcde81c85 Reviewed-on: https://go-review.googlesource.com/c/go/+/336449 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Keith Randall <khr@golang.org>
-rw-r--r--src/runtime/malloc.go20
1 files changed, 9 insertions, 11 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 2759bbdaf9..cc22b0f276 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -1135,13 +1135,21 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
msanmalloc(x, size)
}
+ if rate := MemProfileRate; rate > 0 {
+ // Note cache c only valid while m acquired; see #47302
+ if rate != 1 && size < c.nextSample {
+ c.nextSample -= size
+ } else {
+ profilealloc(mp, x, size)
+ }
+ }
mp.mallocing = 0
releasem(mp)
// Pointerfree data can be zeroed late in a context where preemption can occur.
// x will keep the memory alive.
if !isZeroed && needzero {
- memclrNoHeapPointersChunked(size, x)
+ memclrNoHeapPointersChunked(size, x) // This is a possible preemption point: see #47302
}
if debug.malloc {
@@ -1155,16 +1163,6 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
}
}
- if rate := MemProfileRate; rate > 0 {
- if rate != 1 && size < c.nextSample {
- c.nextSample -= size
- } else {
- mp := acquirem()
- profilealloc(mp, x, size)
- releasem(mp)
- }
- }
-
if assistG != nil {
// Account for internal fragmentation in the assist
// debt now that we know it.