From: Michael Pratt Date: Tue, 1 Nov 2022 21:27:41 +0000 (-0400) Subject: runtime: yield in goschedIfBusy if gp.preempt X-Git-Tag: go1.20rc1~402 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=50664c236f9ab38cd57e0a36cf29527d4c513010;p=gostls13.git runtime: yield in goschedIfBusy if gp.preempt 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 TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Reviewed-by: Cherry Mui --- diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 4285ff6b7c..a04c7b41aa 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -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)