aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgc.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2020-04-15 18:01:00 +0000
committerMichael Knyszek <mknyszek@google.com>2020-04-16 02:35:01 +0000
commit03ba6b070d625bf00eac5350c4f363e5e87828b2 (patch)
tree55f0d7ba160e89a9ea4c36d88da13611fb2460fb /src/runtime/mgc.go
parentc4961dc247ca39c251a5a3c80ebfe59609b4e669 (diff)
downloadgo-03ba6b070d625bf00eac5350c4f363e5e87828b2.tar.gz
go-03ba6b070d625bf00eac5350c4f363e5e87828b2.zip
runtime: prevent preemption while releasing worldsema in gcStart
Currently, as a result of us releasing worldsema now to allow STW events during a mark phase, we release worldsema between starting the world and having the goroutine block in STW mode. This inserts preemption points which, if followed through, could lead to a deadlock. Specifically, because user goroutine scheduling is disabled in STW mode, the goroutine will block before properly releasing worldsema. The fix here is to prevent preemption while releasing the worldsema. Fixes #38404. Updates #19812. Change-Id: I8ed5b3aa108ab2e4680c38e77b0584fb75690e3d Reviewed-on: https://go-review.googlesource.com/c/go/+/228337 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/mgc.go')
-rw-r--r--src/runtime/mgc.go10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 08159e219a..58b76bca70 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -1373,6 +1373,10 @@ func gcStart(trigger gcTrigger) {
// the world.
gcController.markStartTime = now
+ // In STW mode, we could block the instant systemstack
+ // returns, so make sure we're not preemptible.
+ mp = acquirem()
+
// Concurrent mark.
systemstack(func() {
now = startTheWorldWithSema(trace.enabled)
@@ -1385,10 +1389,10 @@ func gcStart(trigger gcTrigger) {
// this goroutine becomes runnable again, and we could
// self-deadlock otherwise.
semrelease(&worldsema)
+ releasem(mp)
- // In STW mode, we could block the instant systemstack
- // returns, so don't do anything important here. Make sure we
- // block rather than returning to user code.
+ // Make sure we block instead of returning to user code
+ // in STW mode.
if mode != gcBackgroundMode {
Gosched()
}