runtime: add goschedIfBusy to bgsweep to prevent livelock after inlining

gcMarkTermination() ensures that all caches are flushed before continuing the GC cycle, thus preempting all goroutines.
However, inlining calls to lock() in bgsweep makes it non-preemptible for most of the time, leading to livelock.
This change adds explicit preemption to avoid this.

Fixes #73499.

Change-Id: I4abf0d658f3d7a03ad588469cd013a0639de0c8a
Reviewed-on: https://go-review.googlesource.com/c/go/+/668795
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
ArsenySamoylov 2025-04-25 14:28:52 +03:00 committed by Gopher Robot
parent 343e486bfd
commit e666f1dabf
1 changed files with 4 additions and 0 deletions

View File

@ -313,6 +313,10 @@ func bgsweep(c chan int) {
// gosweepone returning ^0 above
// and the lock being acquired.
unlock(&sweep.lock)
// This goroutine must preempt when we have no work to do
// but isSweepDone returns false because of another existing sweeper.
// See issue #73499.
goschedIfBusy()
continue
}
sweep.parked = true