Commit 3c2a21ff authored by Austin Clements's avatar Austin Clements

runtime: fix transient _Gwaiting states in newstack

With concurrent stack shrinking, the stack can move the instant after
a G enters _Gwaiting. There are only two places that put a G into
_Gwaiting: gopark and newstack. We fixed uses of gopark. This commit
fixes newstack by simplifying its G transitions and, in particular,
eliminating or narrowing the transient _Gwaiting states it passes
through so it's clear nothing in the G is accessed while in _Gwaiting.

For #12967.

Change-Id: I2440ead411d2bc61beb1e2ab020ebe3cb3481af9
Reviewed-on: https://go-review.googlesource.com/20039Reviewed-by: default avatarRick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 8fb182d0
...@@ -869,11 +869,6 @@ func newstack() { ...@@ -869,11 +869,6 @@ func newstack() {
} }
} }
// The goroutine must be executing in order to call newstack,
// so it must be Grunning (or Gscanrunning).
casgstatus(gp, _Grunning, _Gwaiting)
gp.waitreason = "stack growth"
if gp.stack.lo == 0 { if gp.stack.lo == 0 {
throw("missing stack in newstack") throw("missing stack in newstack")
} }
...@@ -908,6 +903,8 @@ func newstack() { ...@@ -908,6 +903,8 @@ func newstack() {
if thisg.m.p == 0 && thisg.m.locks == 0 { if thisg.m.p == 0 && thisg.m.locks == 0 {
throw("runtime: g is running but p is not") throw("runtime: g is running but p is not")
} }
// Synchronize with scang.
casgstatus(gp, _Grunning, _Gwaiting)
if gp.preemptscan { if gp.preemptscan {
for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) { for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) {
// Likely to be racing with the GC as // Likely to be racing with the GC as
...@@ -941,7 +938,9 @@ func newstack() { ...@@ -941,7 +938,9 @@ func newstack() {
throw("stack overflow") throw("stack overflow")
} }
casgstatus(gp, _Gwaiting, _Gcopystack) // The goroutine must be executing in order to call newstack,
// so it must be Grunning (or Gscanrunning).
casgstatus(gp, _Grunning, _Gcopystack)
// The concurrent GC will not scan the stack while we are doing the copy since // The concurrent GC will not scan the stack while we are doing the copy since
// the gp is in a Gcopystack status. // the gp is in a Gcopystack status.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment