From dd500193d3e96e6bc9700fd43fc68b55e662d7c1 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 27 Oct 2016 21:52:51 -0400 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Rick Hudson --- src/runtime/mgcmark.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 9489a0a3445..954bbef40ca 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -966,7 +966,7 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) { throw("gcDrain phase incorrect") } - gp := getg() + gp := getg().m.curg preemptible := flags&gcDrainUntilPreempt != 0 blocking := flags&(gcDrainUntilPreempt|gcDrainNoBlock) == 0 flushBgCredit := flags&gcDrainFlushBgCredit != 0