The Go programming language
Go to file
Michael Anthony Knyszek 80d306da50 runtime: prevent weak->strong conversions during mark termination
Currently it's possible for weak->strong conversions to create more GC
work during mark termination. When a weak->strong conversion happens
during the mark phase, we need to mark the newly-strong pointer, since
it may now be the only pointer to that object. In other words, the
object could be white.

But queueing new white objects creates GC work, and if this happens
during mark termination, we could end up violating mark termination
invariants. In the parlance of the mark termination algorithm, the
weak->strong conversion is a non-monotonic source of GC work, unlike the
write barriers (which will eventually only see black objects).

This change fixes the problem by forcing weak->strong conversions to
block during mark termination. We can do this efficiently by setting a
global flag before the ragged barrier that is checked at each
weak->strong conversion. If the flag is set, then the conversions block.
The ragged barrier ensures that all Ps have observed the flag and that
any weak->strong conversions which completed before the ragged barrier
have their newly-minted strong pointers visible in GC work queues if
necessary. We later unset the flag and wake all the blocked goroutines
during the mark termination STW.

There are a few subtleties that we need to account for. For one, it's
possible that a goroutine which blocked in a weak->strong conversion
wakes up only to find it's mark termination time again, so we need to
recheck the global flag on wake. We should also stay non-preemptible
while performing the check, so that if the check *does* appear as true,
it cannot switch back to false while we're actively trying to block. If
it switches to false while we try to block, then we'll be stuck in the
queue until the following GC.

All-in-all, this CL is more complicated than I would have liked, but
it's the only idea so far that is clearly correct to me at a high level.

This change adds a test which is somewhat invasive as it manipulates
mark termination, but hopefully that infrastructure will be useful for
debugging, fixing, and regression testing mark termination whenever we
do fix it.

Fixes #69803.

Change-Id: Ie314e6fd357c9e2a07a9be21f217f75f7aba8c4a
Reviewed-on: https://go-review.googlesource.com/c/go/+/623615
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-11-13 18:52:12 +00:00
.github .github: update language change proposal template 2024-08-08 19:02:29 +00:00
api debug/elf: add SHT_GNU_VERDEF section parsing 2024-11-07 15:23:24 +00:00
doc doc/go_mem: fix broken paper link in go_mem.html 2024-11-12 17:16:27 +00:00
lib lib/time: update to 2024b/2024b 2024-09-23 14:25:08 +00:00
misc misc/wasm: move wasm runtime files to lib/wasm 2024-08-30 19:15:21 +00:00
src runtime: prevent weak->strong conversions during mark termination 2024-11-13 18:52:12 +00:00
test cmd/compile: wire up math/bits.TrailingZeros intrinsics for loong64 2024-11-13 00:57:25 +00:00
.gitattributes
.gitignore runtime,internal: move runtime/internal/sys to internal/runtime/sys 2024-07-23 19:05:35 +00:00
CONTRIBUTING.md doc: normalize proposal-process links 2023-03-29 22:00:27 +00:00
LICENSE LICENSE: update per Google Legal 2024-08-09 14:54:31 +00:00
PATENTS
README.md README: fix CC BY license name 2024-07-22 17:45:27 +00:00
SECURITY.md SECURITY.md: update the Reporting a Vulnerability link 2023-09-22 21:17:24 +00:00
codereview.cfg codereview.cfg: add codereview.cfg for master branch 2021-02-19 18:44:53 +00:00
go.env cmd/go: additional doc-inspired tests and bug fixes 2023-06-06 19:18:46 +00:00

README.md

The Go Programming Language

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

Gopher image Gopher image by Renee French, licensed under Creative Commons 4.0 Attribution license.

Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.

Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.

Download and Install

Binary Distributions

Official binary distributions are available at https://go.dev/dl/.

After downloading a binary release, visit https://go.dev/doc/install for installation instructions.

Install From Source

If a binary distribution is not available for your combination of operating system and architecture, visit https://go.dev/doc/install/source for source installation instructions.

Contributing

Go is the work of thousands of contributors. We appreciate your help!

To contribute, please read the contribution guidelines at https://go.dev/doc/contribute.

Note that the Go project uses the issue tracker for bug reports and proposals only. See https://go.dev/wiki/Questions for a list of places to ask questions about the Go language.