runtime: (theoretically) redundant package check in isAsyncSafePoint #72031
Labels
compiler/runtime
Issues related to the Go compiler and/or runtime.
Implementation
Issues describing a semantics-preserving change to the Go implementation.
NeedsFix
The path to resolution is known, but the work has not been done.
Milestone
runtime.isAsyncSafePoint
determines if it safe to preempt a PC.We always consider the runtime unsafe since it contains a bunch of different unsafe areas (long term we'd like to be more precise).
isAsyncSafePoint
has a check if the PC is from a runtime package. This check is a bit odd for a few reasons:objabi
), notably it is missinginternal/runtime/...
. This is what first brought this code to my attention.Given (2), I tried removing the check entirely, which caused spectacular crashes, so it is definitely necessary.
There are a few problems in the way of removing this check:
The check looks at the innermost function of a PC because a runtime function may be inlined into a non-runtime function (Originally added in https://go.dev/cl/211978 for runtime.UnlockOSThread). But the compiler only marks functions as unsafe when compiling a runtime package, which is not the case at the inlining site. The compiler should check if it inlined a runtime function (or simply not inline runtime functions).
Additionally, it's not strictly an issue, but looking at the inline tree to determine safety is rather fragile. After inlining and optimizations it wouldn't be difficult to land on a PC that is reported as part of the outer function but it still technically within an unsafe region. More robust would be for the entire outer function to get marked as unsafe (or, again, don't inline runtime functions).
Second, despite the compiling runtime check, runtime functions still end up with safe points. e.g., I got crashes after preemption of
runtime.typePointers.next
. Looking at "preempt safety" from @randall77'sgithub.com/randall77/dumpgc
:Despite being in the runtime (and
//go:nosplit
!), the function prologue is still marked as unsafe. I think this because the compiler's safety decision is in SSA, but the prologue is incmd/internal/obj
, which is fairly far removed.obj
should probably apply the same policy as SSA.cc @cherrymui @mknyszek @golang/runtime
The text was updated successfully, but these errors were encountered: