Skip to content

Commit 95a6f11

Browse files
committed
runtime: work around "P has cached GC work" failures
We still don't understand what's causing there to be remaining GC work when we enter mark termination, but in order to move forward on this issue, this CL implements a work-around for the problem. If debugCachedWork is false, this CL does a second check for remaining GC work as soon as it stops the world for mark termination. If it finds any work, it starts the world again and re-enters concurrent mark. This will increase STW time by a small amount proportional to GOMAXPROCS, but fixes a serious correctness issue. This works-around #27993. Change-Id: Ia23b85dd6c792ee8d623428bd1a3115631e387b8 Reviewed-on: https://go-review.googlesource.com/c/156140 Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Rick Hudson <[email protected]>
1 parent 9a7278a commit 95a6f11

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

src/runtime/mgc.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@ var gcMarkDoneFlushed uint32
13671367
// termination.
13681368
//
13691369
// For debugging issue #27993.
1370-
const debugCachedWork = true
1370+
const debugCachedWork = false
13711371

13721372
// gcWorkPauseGen is for debugging the mark completion algorithm.
13731373
// gcWork put operations spin while gcWork.pauseGen == gcWorkPauseGen.
@@ -1525,6 +1525,33 @@ top:
15251525
throw("throwOnGCWork")
15261526
}
15271527
}
1528+
} else {
1529+
// For unknown reasons (see issue #27993), there is
1530+
// sometimes work left over when we enter mark
1531+
// termination. Detect this and resume concurrent
1532+
// mark. This is obviously unfortunate.
1533+
//
1534+
// Switch to the system stack to call wbBufFlush1,
1535+
// though in this case it doesn't matter because we're
1536+
// non-preemptible anyway.
1537+
restart := false
1538+
systemstack(func() {
1539+
for _, p := range allp {
1540+
wbBufFlush1(p)
1541+
if !p.gcw.empty() {
1542+
restart = true
1543+
break
1544+
}
1545+
}
1546+
})
1547+
if restart {
1548+
getg().m.preemptoff = ""
1549+
systemstack(func() {
1550+
now := startTheWorldWithSema(true)
1551+
work.pauseNS += now - work.pauseStart
1552+
})
1553+
goto top
1554+
}
15281555
}
15291556

15301557
// Disable assists and background workers. We must do

0 commit comments

Comments
 (0)