From 745349712e837ef77eb7b5a21c4d4e5c7ca0371a Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Thu, 4 Dec 2025 23:27:03 +0000 Subject: runtime: don't count nGsyscallNoP for extra Ms in C In #76435, it turns out that the new metric /sched/goroutines/not-in-go:goroutines counts C threads that have called into Go before (on Linux) as not-in-go goroutines. The reason for this is that the M is still attached to the C thread on Linux as an optimization, so we don't go through all the trouble of detaching the M and, of course, decrementing nGsyscallNoP. There's an easy fix to this accounting issue. The flag on the M, isExtraInC, says whether a thread with an extra M attached no longer has any Go on its (logical) stack. When we take the P from an M in this state, we simply just don't increment nGsyscallNoP. When it calls back into Go, we similarly skip the decrement to nGsyscallNoP. This is more efficient than alternatives, like always updating nGsyscallNoP in cgocallbackg, since that would add a new read-modify-write atomic onto that fast path. It does mean we count threads in C with a P still attached as not-in-go, but this transient in most real programs, assuming the thread indeed does not call back into Go any time soon. Fixes #76435. Change-Id: Id05563bacbe35d3fae17d67fb5ed45fa43fa0548 Reviewed-on: https://go-review.googlesource.com/c/go/+/726964 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Pratt --- src/runtime/runtime2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/runtime/runtime2.go') diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go index cd75e2dd7c..fde378ff25 100644 --- a/src/runtime/runtime2.go +++ b/src/runtime/runtime2.go @@ -945,7 +945,7 @@ type schedt struct { nmfreed int64 // cumulative number of freed m's ngsys atomic.Int32 // number of system goroutines - nGsyscallNoP atomic.Int32 // number of goroutines in syscalls without a P + nGsyscallNoP atomic.Int32 // number of goroutines in syscalls without a P but whose M is not isExtraInC pidle puintptr // idle p's npidle atomic.Int32 -- cgit v1.3