]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: donate racectx to g0 in ReadMetricsSlow
authorMichael Anthony Knyszek <mknyszek@google.com>
Fri, 3 Nov 2023 17:16:51 +0000 (17:16 +0000)
committerGopher Robot <gobot@golang.org>
Fri, 3 Nov 2023 17:39:26 +0000 (17:39 +0000)
ReadMetricsSlow was updated to call the core of readMetrics on the
systemstack to prevent issues with stat skew if the stack gets moved
between readmemstats_m and readMetrics. However, readMetrics calls into
the map implementation, which has race instrumentation. The system stack
typically has no racectx set, resulting in crashes.

Donate racectx to g0 like the tracer does, so that these accesses don't
crash.

For #60607.

Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-race
Change-Id: Ic0251af2d9b60361f071fe97084508223109480c
Reviewed-on: https://go-review.googlesource.com/c/go/+/539695
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>

src/runtime/export_test.go

index 96b3a8dd93b41a7feaf44c72d4846fcbced3b1ee..b60c1f0a69d1d44dc5bfa6c7f4e81865234556b1 100644 (file)
@@ -425,6 +425,10 @@ func ReadMetricsSlow(memStats *MemStats, samplesp unsafe.Pointer, len, cap int)
        initMetrics()
 
        systemstack(func() {
+               // Donate the racectx to g0. readMetricsLocked calls into the race detector
+               // via map access.
+               getg().racectx = getg().m.curg.racectx
+
                // Read the metrics once before in case it allocates and skews the metrics.
                // readMetricsLocked is designed to only allocate the first time it is called
                // with a given slice of samples. In effect, this extra read tests that this
@@ -442,6 +446,9 @@ func ReadMetricsSlow(memStats *MemStats, samplesp unsafe.Pointer, len, cap int)
                // system stack with readmemstats_m so that we don't call into
                // the stack allocator and adjust metrics between there and here.
                readMetricsLocked(samplesp, len, cap)
+
+               // Undo the donation.
+               getg().racectx = 0
        })
        metricsUnlock()