diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 6bc2d73d557..c4c922bda8d 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -258,6 +258,9 @@ func gcAssistAlloc(size uintptr, allowAssist bool) { // work is done here. //go:nowritebarrier func gcphasework(gp *g) { + if gp.gcworkdone { + return + } switch gcphase { default: throw("gcphasework in bad gcphase") diff --git a/src/runtime/stack1.go b/src/runtime/stack1.go index f77e87cdf9c..5c2388d0e6f 100644 --- a/src/runtime/stack1.go +++ b/src/runtime/stack1.go @@ -743,8 +743,11 @@ func newstack() { } if gp.preemptscan { for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) { - // Likely to be racing with the GC as it sees a _Gwaiting and does the stack scan. - // If so this stack will be scanned twice which does not change correctness. + // Likely to be racing with the GC as + // it sees a _Gwaiting and does the + // stack scan. If so, gcworkdone will + // be set and gcphasework will simply + // return. } gcphasework(gp) casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting)