Commit 3526d803 authored by Austin Clements's avatar Austin Clements

runtime: allow write barriers in gchelper

We're about to start tracking nowritebarrierrec through systemstack
calls, which detects that we're calling markroot (which has write
barriers) from gchelper, which is called from the scheduler during STW
apparently without a P.

But it turns out that func helpgc, which wakes up blocked Ms to run
gchelper, installs a P for gchelper to use. This means there *is* a P
when gchelper runs, so it is allowed to have write barriers. Tell the
compiler this by marking gchelper go:yeswritebarrierrec. Also,
document the call to gchelper so I don't have to spend another half a
day puzzling over how on earth this could possibly work before
discovering the spooky action-at-a-distance in helpgc.

Updates #22384.
For #22460.

Change-Id: I7394c9b4871745575f87a2d4fbbc5b8e54d669f7
Reviewed-on: https://go-review.googlesource.com/72772
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent d941b075
...@@ -2099,9 +2099,14 @@ func clearpools() { ...@@ -2099,9 +2099,14 @@ func clearpools() {
unlock(&sched.deferlock) unlock(&sched.deferlock)
} }
// Timing // gchelper runs mark termination tasks on Ps other than the P
// coordinating mark termination.
//go:nowritebarrier //
// The caller is responsible for ensuring that this has a P to run on,
// even though it's running during STW. Because of this, it's allowed
// to have write barriers.
//
//go:yeswritebarrierrec
func gchelper() { func gchelper() {
_g_ := getg() _g_ := getg()
_g_.m.traceback = 2 _g_.m.traceback = 2
...@@ -2136,6 +2141,8 @@ func gchelperstart() { ...@@ -2136,6 +2141,8 @@ func gchelperstart() {
} }
} }
// Timing
// itoaDiv formats val/(10**dec) into buf. // itoaDiv formats val/(10**dec) into buf.
func itoaDiv(buf []byte, val uint64, dec int) []byte { func itoaDiv(buf []byte, val uint64, dec int) []byte {
i := len(buf) - 1 i := len(buf) - 1
......
...@@ -1938,7 +1938,9 @@ retry: ...@@ -1938,7 +1938,9 @@ retry:
notesleep(&_g_.m.park) notesleep(&_g_.m.park)
noteclear(&_g_.m.park) noteclear(&_g_.m.park)
if _g_.m.helpgc != 0 { if _g_.m.helpgc != 0 {
// helpgc() set _g_.m.p and _g_.m.mcache, so we have a P.
gchelper() gchelper()
// Undo the effects of helpgc().
_g_.m.helpgc = 0 _g_.m.helpgc = 0
_g_.m.mcache = nil _g_.m.mcache = nil
_g_.m.p = 0 _g_.m.p = 0
......
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