From 0b31e6d4cc804ab76ae8ced151ee2f50657aec14 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 3 Apr 2025 03:26:25 +0000 Subject: runtime: cleanup M vgetrandom state before dropping P When an M is destroyed, we put its vgetrandom state back on the shared list for another M to reuse. This list is simply a slice, so appending to the slice may allocate. Currently this operation is performed in mdestroy, after the P is released, meaning allocation is not allowed. More the cleanup earlier in mdestroy when allocation is still OK. Also add //go:nowritebarrierrec to mdestroy since it runs without a P, which would have caught this bug. Fixes #73141. Change-Id: I6a6a636c3fbf5c6eec09d07a260e39dbb4d2db12 Reviewed-on: https://go-review.googlesource.com/c/go/+/662455 Reviewed-by: Jason Donenfeld LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall Reviewed-by: Keith Randall --- src/runtime/os_linux.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/runtime/os_linux.go') diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go index 55c4ac8f61..f24d18027b 100644 --- a/src/runtime/os_linux.go +++ b/src/runtime/os_linux.go @@ -412,13 +412,12 @@ func unminit() { getg().m.procid = 0 } -// Called from exitm, but not from drop, to undo the effect of thread-owned +// Called from mexit, but not from dropm, to undo the effect of thread-owned // resources in minit, semacreate, or elsewhere. Do not take locks after calling this. +// +// This always runs without a P, so //go:nowritebarrierrec is required. +//go:nowritebarrierrec func mdestroy(mp *m) { - if mp.vgetrandomState != 0 { - vgetrandomPutState(mp.vgetrandomState) - mp.vgetrandomState = 0 - } } // #ifdef GOARCH_386 -- cgit v1.3