diff options
author | Nikhil Benesch <nikhil.benesch@gmail.com> | 2018-11-09 00:55:13 -0500 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2018-11-10 19:26:41 +0000 |
commit | 8e0ec5ec09f92464730f89ff1f05e847b881a58a (patch) | |
tree | 4e26a0aba670220044d50a6d950f65bf58412099 /src/runtime/runtime2.go | |
parent | e4c1feef74d7415ba134aa0950f7f285a3e1902a (diff) | |
download | go-git-8e0ec5ec09f92464730f89ff1f05e847b881a58a.tar.gz |
runtime: ensure m.p is never stale
When a goroutine enters a syscall, its M unwires from its P to allow
the P to be retaken by another M if the syscall is slow. The M retains a
reference to its old P, however, so that if its old P has not been
retaken when the syscall returns, it can quickly reacquire that P.
The implementation, however, was confusing, as it left the reference to
the potentially-retaken P in m.p, which implied that the P was still
wired.
Make the code clearer by enforcing the invariant that m.p is never
stale. entersyscall now moves m.p to m.oldp and sets m.p to 0;
exitsyscall does the reverse, provided m.oldp has not been retaken.
With this scheme in place, the issue described in #27660 (assertion
failures in the race detector) would have resulted in a clean segfault
instead of silently corrupting memory.
Change-Id: Ib3e03623ebed4f410e852a716919fe4538858f0a
Reviewed-on: https://go-review.googlesource.com/c/148899
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/runtime2.go')
-rw-r--r-- | src/runtime/runtime2.go | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index bbb66bb8fa..66dd1b19c1 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -417,6 +417,7 @@ type m struct { caughtsig guintptr // goroutine running during fatal signal p puintptr // attached p for executing go code (nil if not executing go code) nextp puintptr + oldp puintptr // the p that was attached before executing a syscall id int64 mallocing int32 throwing int32 |