diff options
author | Michael Pratt <mpratt@google.com> | 2021-03-10 16:06:47 -0500 |
---|---|---|
committer | Alexander Rakoczy <alex@golang.org> | 2021-03-12 20:01:03 +0000 |
commit | 0da04a662a8e46f688bc65bf4fc5440226babe59 (patch) | |
tree | 2c3871fa7ca2d0f16836a2dd6612c85b2a2ccf44 /src/runtime | |
parent | 3979fb9af9ccfc0b7ccb613dcf256b18c2c295f0 (diff) | |
download | go-0da04a662a8e46f688bc65bf4fc5440226babe59.tar.gz go-0da04a662a8e46f688bc65bf4fc5440226babe59.zip |
[release-branch.go1.16] runtime, time: disable preemption in addtimer
The timerpMask optimization updates a mask of Ps (potentially)
containing timers in pidleget / pidleput. For correctness, it depends on
the assumption that new timers can only be added to a P's own heap.
addtimer violates this assumption if it is preempted after computing pp.
That G may then run on a different P, but adding a timer to the original
P's heap.
Avoid this by disabling preemption while pp is in use.
Other uses of doaddtimer should be OK:
* moveTimers: always moves to the current P's heap
* modtimer, cleantimers, addAdjustedTimers, runtimer: does not add net
new timers to the heap while locked
For #44868
Fixes #44869
Change-Id: I4a5d080865e854931d0a3a09a51ca36879101d72
Reviewed-on: https://go-review.googlesource.com/c/go/+/300610
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit aa26687e457d825fc9c580e8c029b768e0e70d38)
Reviewed-on: https://go-review.googlesource.com/c/go/+/300611
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/time.go | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go index 8ab2a03430..dee6a674e4 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -263,6 +263,9 @@ func addtimer(t *timer) { when := t.when + // Disable preemption while using pp to avoid changing another P's heap. + mp := acquirem() + pp := getg().m.p.ptr() lock(&pp.timersLock) cleantimers(pp) @@ -270,6 +273,8 @@ func addtimer(t *timer) { unlock(&pp.timersLock) wakeNetPoller(when) + + releasem(mp) } // doaddtimer adds t to the current P's heap. |