1
0
mirror of https://github.com/golang/go synced 2024-11-24 08:40:14 -07:00

runtime: fix preemption of fractional and idle mark workers

Currently, gcDrain looks for the preemption flag at getg().preempt.
However, commit d6625ca moved mark worker draining to the system
stack, which means getg() returns the g0, which never has the preempt
flag set, so idle and fractional workers don't get preempted after
10ms and just run until they run out of work. As a result, if there's
enough idle time, GC becomes effectively STW.

Fix this by looking for the preemption flag on getg().m.curg, which
will always be the user G (where the preempt flag is set), regardless
of whether gcDrain is running on the user or the g0 stack.

Change-Id: Ib554cf49a705b86ccc3d08940bc869f868c50dd2
Reviewed-on: https://go-review.googlesource.com/32251
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
Austin Clements 2016-10-27 21:52:51 -04:00
parent ca922b6d36
commit dd500193d3

View File

@ -966,7 +966,7 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) {
throw("gcDrain phase incorrect") throw("gcDrain phase incorrect")
} }
gp := getg() gp := getg().m.curg
preemptible := flags&gcDrainUntilPreempt != 0 preemptible := flags&gcDrainUntilPreempt != 0
blocking := flags&(gcDrainUntilPreempt|gcDrainNoBlock) == 0 blocking := flags&(gcDrainUntilPreempt|gcDrainNoBlock) == 0
flushBgCredit := flags&gcDrainFlushBgCredit != 0 flushBgCredit := flags&gcDrainFlushBgCredit != 0