aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/time.go
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2021-03-10 16:06:47 -0500
committerMichael Pratt <mpratt@google.com>2021-03-10 21:49:24 +0000
commitaa26687e457d825fc9c580e8c029b768e0e70d38 (patch)
treedf0abfda05ee4b91575a5dfbfeba2f0c43c52c9a /src/runtime/time.go
parentf9ed8b3f1e180d3cd8534897103683e8165df5f0 (diff)
downloadgo-aa26687e457d825fc9c580e8c029b768e0e70d38.tar.gz
go-aa26687e457d825fc9c580e8c029b768e0e70d38.zip
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 Fixes #44868 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>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r--src/runtime/time.go5
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.