From 50664c236f9ab38cd57e0a36cf29527d4c513010 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Tue, 1 Nov 2022 17:27:41 -0400 Subject: [PATCH] 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 --- src/runtime/proc.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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) -- 2.50.0