]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: allow write barriers in gchelper
authorAustin Clements <austin@google.com>
Sun, 22 Oct 2017 22:10:08 +0000 (18:10 -0400)
committerAustin Clements <austin@google.com>
Sun, 29 Oct 2017 17:56:21 +0000 (17:56 +0000)
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: Rick Hudson <rlh@golang.org>
src/runtime/mgc.go
src/runtime/proc.go

index c1edd17842aae89325c8325f63d0514e068245c6..628a77fc1ebca089bfc979a19bcf4dd9b082c045 100644 (file)
@@ -2099,9 +2099,14 @@ func clearpools() {
        unlock(&sched.deferlock)
 }
 
-// Timing
-
-//go:nowritebarrier
+// gchelper runs mark termination tasks on Ps other than the P
+// coordinating mark termination.
+//
+// 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() {
        _g_ := getg()
        _g_.m.traceback = 2
@@ -2136,6 +2141,8 @@ func gchelperstart() {
        }
 }
 
+// Timing
+
 // itoaDiv formats val/(10**dec) into buf.
 func itoaDiv(buf []byte, val uint64, dec int) []byte {
        i := len(buf) - 1
index af9b33886c0624ace89d6a0e2dbedb4c198e9317..8383eb51a1c72a4c4f9426ad743f56cab9cc193a 100644 (file)
@@ -1938,7 +1938,9 @@ retry:
        notesleep(&_g_.m.park)
        noteclear(&_g_.m.park)
        if _g_.m.helpgc != 0 {
+               // helpgc() set _g_.m.p and _g_.m.mcache, so we have a P.
                gchelper()
+               // Undo the effects of helpgc().
                _g_.m.helpgc = 0
                _g_.m.mcache = nil
                _g_.m.p = 0