Skip to content

Commit 64c22b7

Browse files
committed
Revert "runtime: don't hold worldsema across mark phase"
This reverts commit 7b294cd, CL 182657. Reason for revert: This change may be causing latency problems for applications which call ReadMemStats, because it may cause all goroutines to stop until the GC completes. https://golang.org/cl/215157 fixes this problem, but it's too late in the cycle to land that. Updates #19812. Change-Id: Iaa26f4dec9b06b9db2a771a44e45f58d0aa8f26d Reviewed-on: https://go-review.googlesource.com/c/go/+/216358 Run-TryBot: Michael Knyszek <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent ad3cef1 commit 64c22b7

File tree

5 files changed

+13
-62
lines changed

5 files changed

+13
-62
lines changed

src/runtime/debug.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ func GOMAXPROCS(n int) int {
2626
return ret
2727
}
2828

29-
stopTheWorldGC("GOMAXPROCS")
29+
stopTheWorld("GOMAXPROCS")
3030

3131
// newprocs will be processed by startTheWorld
3232
newprocs = int32(n)
3333

34-
startTheWorldGC()
34+
startTheWorld()
3535
return ret
3636
}
3737

src/runtime/mgc.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,6 @@ func gcStart(trigger gcTrigger) {
12691269
}
12701270

12711271
// Ok, we're doing it! Stop everybody else
1272-
semacquire(&gcsema)
12731272
semacquire(&worldsema)
12741273

12751274
if trace.enabled {
@@ -1375,7 +1374,6 @@ func gcStart(trigger gcTrigger) {
13751374
Gosched()
13761375
}
13771376

1378-
semrelease(&worldsema)
13791377
semrelease(&work.startSema)
13801378
}
13811379

@@ -1438,10 +1436,6 @@ top:
14381436
return
14391437
}
14401438

1441-
// forEachP needs worldsema to execute, and we'll need it to
1442-
// stop the world later, so acquire worldsema now.
1443-
semacquire(&worldsema)
1444-
14451439
// Flush all local buffers and collect flushedWork flags.
14461440
gcMarkDoneFlushed = 0
14471441
systemstack(func() {
@@ -1502,7 +1496,6 @@ top:
15021496
// work to do. Keep going. It's possible the
15031497
// transition condition became true again during the
15041498
// ragged barrier, so re-check it.
1505-
semrelease(&worldsema)
15061499
goto top
15071500
}
15081501

@@ -1579,7 +1572,6 @@ top:
15791572
now := startTheWorldWithSema(true)
15801573
work.pauseNS += now - work.pauseStart
15811574
})
1582-
semrelease(&worldsema)
15831575
goto top
15841576
}
15851577
}
@@ -1797,7 +1789,6 @@ func gcMarkTermination(nextTriggerRatio float64) {
17971789
}
17981790

17991791
semrelease(&worldsema)
1800-
semrelease(&gcsema)
18011792
// Careful: another GC cycle may start now.
18021793

18031794
releasem(mp)

src/runtime/proc.go

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -857,23 +857,8 @@ func casGFromPreempted(gp *g, old, new uint32) bool {
857857
// goroutines.
858858
func stopTheWorld(reason string) {
859859
semacquire(&worldsema)
860-
gp := getg()
861-
gp.m.preemptoff = reason
862-
systemstack(func() {
863-
// Mark the goroutine which called stopTheWorld preemptible so its
864-
// stack may be scanned.
865-
// This lets a mark worker scan us while we try to stop the world
866-
// since otherwise we could get in a mutual preemption deadlock.
867-
// We must not modify anything on the G stack because a stack shrink
868-
// may occur. A stack shrink is otherwise OK though because in order
869-
// to return from this function (and to leave the system stack) we
870-
// must have preempted all goroutines, including any attempting
871-
// to scan our stack, in which case, any stack shrinking will
872-
// have already completed by the time we exit.
873-
casgstatus(gp, _Grunning, _Gwaiting)
874-
stopTheWorldWithSema()
875-
casgstatus(gp, _Gwaiting, _Grunning)
876-
})
860+
getg().m.preemptoff = reason
861+
systemstack(stopTheWorldWithSema)
877862
}
878863

879864
// startTheWorld undoes the effects of stopTheWorld.
@@ -885,31 +870,10 @@ func startTheWorld() {
885870
getg().m.preemptoff = ""
886871
}
887872

888-
// stopTheWorldGC has the same effect as stopTheWorld, but blocks
889-
// until the GC is not running. It also blocks a GC from starting
890-
// until startTheWorldGC is called.
891-
func stopTheWorldGC(reason string) {
892-
semacquire(&gcsema)
893-
stopTheWorld(reason)
894-
}
895-
896-
// startTheWorldGC undoes the effects of stopTheWorldGC.
897-
func startTheWorldGC() {
898-
startTheWorld()
899-
semrelease(&gcsema)
900-
}
901-
902-
// Holding worldsema grants an M the right to try to stop the world.
873+
// Holding worldsema grants an M the right to try to stop the world
874+
// and prevents gomaxprocs from changing concurrently.
903875
var worldsema uint32 = 1
904876

905-
// Holding gcsema grants the M the right to block a GC, and blocks
906-
// until the current GC is done. In particular, it prevents gomaxprocs
907-
// from changing concurrently.
908-
//
909-
// TODO(mknyszek): Once gomaxprocs and the execution tracer can handle
910-
// being changed/enabled during a GC, remove this.
911-
var gcsema uint32 = 1
912-
913877
// stopTheWorldWithSema is the core implementation of stopTheWorld.
914878
// The caller is responsible for acquiring worldsema and disabling
915879
// preemption first and then should stopTheWorldWithSema on the system

src/runtime/trace.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,9 @@ func traceBufPtrOf(b *traceBuf) traceBufPtr {
180180
// Most clients should use the runtime/trace package or the testing package's
181181
// -test.trace flag instead of calling StartTrace directly.
182182
func StartTrace() error {
183-
// Stop the world so that we can take a consistent snapshot
183+
// Stop the world, so that we can take a consistent snapshot
184184
// of all goroutines at the beginning of the trace.
185-
// Do not stop the world during GC so we ensure we always see
186-
// a consistent view of GC-related events (e.g. a start is always
187-
// paired with an end).
188-
stopTheWorldGC("start tracing")
185+
stopTheWorld("start tracing")
189186

190187
// We are in stop-the-world, but syscalls can finish and write to trace concurrently.
191188
// Exitsyscall could check trace.enabled long before and then suddenly wake up
@@ -196,7 +193,7 @@ func StartTrace() error {
196193

197194
if trace.enabled || trace.shutdown {
198195
unlock(&trace.bufLock)
199-
startTheWorldGC()
196+
startTheWorld()
200197
return errorString("tracing is already enabled")
201198
}
202199

@@ -267,7 +264,7 @@ func StartTrace() error {
267264

268265
unlock(&trace.bufLock)
269266

270-
startTheWorldGC()
267+
startTheWorld()
271268
return nil
272269
}
273270

@@ -276,14 +273,14 @@ func StartTrace() error {
276273
func StopTrace() {
277274
// Stop the world so that we can collect the trace buffers from all p's below,
278275
// and also to avoid races with traceEvent.
279-
stopTheWorldGC("stop tracing")
276+
stopTheWorld("stop tracing")
280277

281278
// See the comment in StartTrace.
282279
lock(&trace.bufLock)
283280

284281
if !trace.enabled {
285282
unlock(&trace.bufLock)
286-
startTheWorldGC()
283+
startTheWorld()
287284
return
288285
}
289286

@@ -320,7 +317,7 @@ func StopTrace() {
320317
trace.shutdown = true
321318
unlock(&trace.bufLock)
322319

323-
startTheWorldGC()
320+
startTheWorld()
324321

325322
// The world is started but we've set trace.shutdown, so new tracing can't start.
326323
// Wait for the trace reader to flush pending buffers and stop.

src/runtime/trace/trace_stack_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ func TestTraceSymbolize(t *testing.T) {
233233
}},
234234
{trace.EvGomaxprocs, []frame{
235235
{"runtime.startTheWorld", 0}, // this is when the current gomaxprocs is logged.
236-
{"runtime.startTheWorldGC", 0},
237236
{"runtime.GOMAXPROCS", 0},
238237
{"runtime/trace_test.TestTraceSymbolize", 0},
239238
{"testing.tRunner", 0},

0 commit comments

Comments
 (0)