diff options
| author | Austin Clements <austin@google.com> | 2016-10-28 11:14:07 -0400 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2016-10-28 18:07:30 +0000 |
| commit | d70b0fe6c4d1b1369b742ea5b7d4e6f0c50ffdcb (patch) | |
| tree | 0de518f1770daa6c1cbb9e66d381fbea53ee99f0 /src/runtime | |
| parent | e14b02197737a0d7e5eed2856806cf20c85052cf (diff) | |
| download | go-d70b0fe6c4d1b1369b742ea5b7d4e6f0c50ffdcb.tar.xz | |
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 <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/mgcmark.go | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 286aeb74a9..7819698def 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -973,7 +973,7 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) { // Drain root marking jobs. if work.markrootNext < work.markrootJobs { - for blocking || !gp.preempt { + for !(preemptible && gp.preempt) { job := atomic.Xadd(&work.markrootNext, +1) - 1 if job >= work.markrootJobs { break |
