From f5ddd94334a63ac8107c976aa4bd6ee2171d7d64 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 8 Dec 2021 15:30:28 -0500 Subject: [PATCH] runtime/pprof: increase systemstack calls in TestLabelSystemstack TestLabelSystemstack needs to collect samples within runtime.systemstack to complete the test. The current approach uses fmt.Fprintf, which gets into systemstack through the allocator and GC, but also does lots of other work. In my measurements, approximately 2% of samples contain runtime.systemstack. The new approach uses debug.SetGCPercent, which uses systemstack for most of its work, including contention on mheap_.lock, which extends usage even more. In my measurements, approximately 99% of samples contain runtime.systemstack. Fixes #50050 Change-Id: I59e5bb756341b716a12e13d2e3fe0adadd7fe956 Reviewed-on: https://go-review.googlesource.com/c/go/+/370375 Reviewed-by: Bryan Mills Trust: Michael Pratt Run-TryBot: Michael Pratt Reviewed-by: Michael Knyszek TryBot-Result: Gopher Robot --- src/runtime/pprof/pprof_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go index 2e6165ff88..b3a8927dc7 100644 --- a/src/runtime/pprof/pprof_test.go +++ b/src/runtime/pprof/pprof_test.go @@ -1425,6 +1425,11 @@ func TestLabelRace(t *testing.T) { // TestLabelSystemstack makes sure CPU profiler samples of goroutines running // on systemstack include the correct pprof labels. See issue #48577 func TestLabelSystemstack(t *testing.T) { + // Grab and re-set the initial value before continuing to ensure + // GOGC doesn't actually change following the test. + gogc := debug.SetGCPercent(100) + debug.SetGCPercent(gogc) + matches := matchAndAvoidStacks(stackContainsLabeled, []string{"runtime.systemstack;key=value"}, avoidFunctions()) p := testCPUProfile(t, matches, func(dur time.Duration) { Do(context.Background(), Labels("key", "value"), func(context.Context) { @@ -1434,7 +1439,7 @@ func TestLabelSystemstack(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - labelHog(stop) + labelHog(stop, gogc) }() } @@ -1467,13 +1472,13 @@ func TestLabelSystemstack(t *testing.T) { // labelHog is designed to burn CPU time in a way that a high number of CPU // samples end up running on systemstack. -func labelHog(stop chan struct{}) { +func labelHog(stop chan struct{}, gogc int) { for i := 0; ; i++ { select { case <-stop: return default: - fmt.Fprintf(io.Discard, "%d", i) + debug.SetGCPercent(gogc) } } } -- 2.50.0