]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: yield in goschedIfBusy if gp.preempt
authorMichael Pratt <mpratt@google.com>
Tue, 1 Nov 2022 21:27:41 +0000 (17:27 -0400)
committerMichael Pratt <mpratt@google.com>
Mon, 7 Nov 2022 17:19:18 +0000 (17:19 +0000)
runtime.bgsweep contains an infinite loop. With aggressive enough
inlining, it may not perform any CALLs on a typical iteration. If
the runtime trying to preempt this goroutine, the lack of CALLs may
prevent preemption for ever occurring.

bgsweep does happen to call goschedIfBusy. Add a preempt check there to
make sure we yield eventually.

For #55022.

Change-Id: If22eb86fd6a626094b3c56dc745c8e4243b0fb40
Reviewed-on: https://go-review.googlesource.com/c/go/+/447135
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/runtime/proc.go

index 4285ff6b7c49dcd4a6920c5b5b0fc8ce89a0a69c..a04c7b41aa9549b175538be233599e5ff84aa45c 100644 (file)
@@ -335,7 +335,10 @@ func goschedguarded() {
 //
 //go:nosplit
 func goschedIfBusy() {
-       if sched.npidle.Load() > 0 {
+       gp := getg()
+       // Call gosched if gp.preempt is set; we may be in a tight loop that
+       // doesn't otherwise yield.
+       if !gp.preempt && sched.npidle.Load() > 0 {
                return
        }
        mcall(gosched_m)