Skip to content

Commit d70b0fe

Browse files
committed
runtime: fix preemption of root marking jobs
The current logic in gcDrain conflates non-blocking with preemptible draining for root jobs. As a result, if you do a non-blocking (but *not* preemptible) drain, like dedicated workers do, the root job drain will stop if preempted and fall through to heap marking jobs, which won't stop until it fails to get a heap marking job. This commit fixes the condition on root marking jobs so they only stop when preempted if the drain is preemptible. Coincidentally, this also fixes a nil pointer dereference if we call gcDrain with gcDrainNoBlock and without a user G, since it tries to get the preempt flag from the nil user G. This combination never happens right now, but will in the future. Change-Id: Ia910ec20a9b46237f7926969144a33b1b4a7b2f9 Reviewed-on: https://go-review.googlesource.com/32291 Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Russ Cox <[email protected]>
1 parent e14b021 commit d70b0fe

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

src/runtime/mgcmark.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) {
973973

974974
// Drain root marking jobs.
975975
if work.markrootNext < work.markrootJobs {
976-
for blocking || !gp.preempt {
976+
for !(preemptible && gp.preempt) {
977977
job := atomic.Xadd(&work.markrootNext, +1) - 1
978978
if job >= work.markrootJobs {
979979
break

0 commit comments

Comments
 (0)