From e666f1dabf5174710919ab7cff3e8afefd9ac049 Mon Sep 17 00:00:00 2001 From: ArsenySamoylov Date: Fri, 25 Apr 2025 14:28:52 +0300 Subject: [PATCH] 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 Auto-Submit: Michael Knyszek Reviewed-by: Michael Knyszek Reviewed-by: Michael Pratt --- src/runtime/mgcsweep.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go index 046dd798c8..f4d43e73f2 100644 --- a/src/runtime/mgcsweep.go +++ b/src/runtime/mgcsweep.go @@ -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 -- 2.51.0