diff options
author | Michael Pratt <mpratt@google.com> | 2021-02-11 10:44:34 -0500 |
---|---|---|
committer | Michael Pratt <mpratt@google.com> | 2021-03-30 21:43:12 +0000 |
commit | 4b1a24f3cd9d49ecbe4c30b6a5ecade70f9dd04f (patch) | |
tree | e28a4931dcc077e67f7190ede23d1d976fb0861e /src/runtime/proc.go | |
parent | e0ce0af6ef5232352852fa027fe51fa3fd01198e (diff) | |
download | go-4b1a24f3cd9d49ecbe4c30b6a5ecade70f9dd04f.tar.gz go-4b1a24f3cd9d49ecbe4c30b6a5ecade70f9dd04f.zip |
runtime: fix G passed to schedEnabled and cleanup
exitsyscall0 contains two G variables: _g_ and gp. _g_ is the active G,
g0, while gp is the G to run (which just exited from a syscall).
It is passing _g_ to schedEnabled, which is incorrect; we are about to
execute gp, so that is what we should be checking the schedulability of.
While this is incorrect and should be fixed, I don't think it has ever
caused a problem in practice:
* g0 does not have g.startpc set, so schedEnabled simplifies to
just !sched.disable.user.
* This is correct provided gp is never a system goroutine.
* As far as I know, system goroutines never use entersyscall /
exitsyscall.
As far I can tell, this was a simple copy/paste error from exitsyscall,
where variable _g_ is the G to run.
While we are here, eliminate _g_ entirely, as the one other use is
identical to using gp.
Change-Id: I5df98a34569238b89ab13ff7012cd756fefb10dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/291329
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/proc.go')
-rw-r--r-- | src/runtime/proc.go | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go index d868c596bf..2a7a766b25 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -3856,15 +3856,15 @@ func exitsyscallfast_pidle() bool { // exitsyscall slow path on g0. // Failed to acquire P, enqueue gp as runnable. // +// Called via mcall, so gp is the calling g from this M. +// //go:nowritebarrierrec func exitsyscall0(gp *g) { - _g_ := getg() - casgstatus(gp, _Gsyscall, _Grunnable) dropg() lock(&sched.lock) var _p_ *p - if schedEnabled(_g_) { + if schedEnabled(gp) { _p_ = pidleget() } if _p_ == nil { @@ -3878,8 +3878,11 @@ func exitsyscall0(gp *g) { acquirep(_p_) execute(gp, false) // Never returns. } - if _g_.m.lockedg != 0 { + if gp.lockedm != 0 { // Wait until another thread schedules gp and so m again. + // + // N.B. lockedm must be this M, as this g was running on this M + // before entersyscall. stoplockedm() execute(gp, false) // Never returns. } |