runtime: dropg before CAS g status to _Grunnable/_Gwaiting
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 17 Jan 2019 02:14:28 +0000 (02:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 17 Jan 2019 02:14:28 +0000 (02:14 +0000)
commitf41bf58736b95ec17b642f4cb9c802facfc1b7bc
treed5b0a5962676f38d7a1eaf75f6116cbef8f04456
parent63dfd55efc0add89bb537cf923fbe11fa195734e
runtime: dropg before CAS g status to _Grunnable/_Gwaiting

    Currently, we dropg (which clears gp.m) after we CAS the g status
    to _Grunnable or _Gwaiting. Immediately after CASing the g status,
    another thread may CAS it to _Gscan status and scan its stack.
    With precise stack scan, it accesses gp.m in order to switch to g
    and back (in doscanstackswitch). This races with dropg. If
    doscanstackswitch reads gp.m, then dropg runs, when we restore
    the m at the end of the scan it will set to a stale value. Worse,
    if dropg runs after doscanstackswitch sets the new m, gp will be
    running with a nil m.

    To fix this, we do dropg before CAS g status to _Grunnable or
    _Gwaiting. We can do this safely if we are CASing from _Grunning,
    as we own the g when it is in _Grunning. There is one case where
    we CAS from _Gsyscall to _Grunnable. It is not safe to dropg when
    it is in _Gsyscall, as precise stack scan needs to read gp.m in
    order to signal the m. So we need to introduce a transient state,
    _Gexitingsyscall, between _Gsyscall and _Grunnable, where the GC
    should not scan its stack.

    In is a little unfortunate that we have to add another g status.
    We could reuse an existing one (e.g. _Gcopystack), but it is
    clearer and safer to just use a new one, as Austin suggested.

    Reviewed-on: https://go-review.googlesource.com/c/158157

From-SVN: r268001
gcc/go/gofrontend/MERGE
libgo/go/runtime/proc.go
libgo/go/runtime/runtime2.go
libgo/go/runtime/traceback_gccgo.go