Skip to content

Commit 433c1d3

Browse files
rhyshgopherbot
authored andcommitted
runtime: store zero-delay mutex contention events
Mutex contention events with delay of 0 need more than CL 604355 added: When deciding which event to store in the M's single available slot, always choose to drop the zero-delay event. Store an explicit flag for whether we have an event to store, rather than relying on a non-zero delay. And, fix a test of sync.Mutex contention that expects those events to have non-zero delay. The reporting of non-runtime contention like this has long allowed zero-delay events, which we see when cputicks has low resolution. Fixes #68892 Fixes #68906 Change-Id: Id412141e4eb09724f3ce195899a20d59c92d7b78 Reviewed-on: https://go-review.googlesource.com/c/go/+/606115 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Rhys Hiltner <rhys.hiltner@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
1 parent 3d9a89b commit 433c1d3

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

src/runtime/mprof.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ type mLockProfile struct {
718718
pending uintptr // *mutex that experienced contention (to be traceback-ed)
719719
cycles int64 // cycles attributable to "pending" (if set), otherwise to "stack"
720720
cyclesLost int64 // contention for which we weren't able to record a call stack
721+
haveStack bool // stack and cycles are to be added to the mutex profile
721722
disabled bool // attribute all time to "lost"
722723
}
723724

@@ -745,6 +746,9 @@ func (prof *mLockProfile) recordLock(cycles int64, l *mutex) {
745746
// We can only store one call stack for runtime-internal lock contention
746747
// on this M, and we've already got one. Decide which should stay, and
747748
// add the other to the report for runtime._LostContendedRuntimeLock.
749+
if cycles == 0 {
750+
return
751+
}
748752
prevScore := uint64(cheaprand64()) % uint64(prev)
749753
thisScore := uint64(cheaprand64()) % uint64(cycles)
750754
if prevScore > thisScore {
@@ -769,7 +773,7 @@ func (prof *mLockProfile) recordUnlock(l *mutex) {
769773
if uintptr(unsafe.Pointer(l)) == prof.pending {
770774
prof.captureStack()
771775
}
772-
if gp := getg(); gp.m.locks == 1 && gp.m.mLockProfile.cycles != 0 {
776+
if gp := getg(); gp.m.locks == 1 && gp.m.mLockProfile.haveStack {
773777
prof.store()
774778
}
775779
}
@@ -795,6 +799,7 @@ func (prof *mLockProfile) captureStack() {
795799
skip += 1 // runtime.unlockWithRank.func1
796800
}
797801
prof.pending = 0
802+
prof.haveStack = true
798803

799804
prof.stack[0] = logicalStackSentinel
800805
if debug.runtimeContentionStacks.Load() == 0 {
@@ -835,6 +840,7 @@ func (prof *mLockProfile) store() {
835840

836841
cycles, lost := prof.cycles, prof.cyclesLost
837842
prof.cycles, prof.cyclesLost = 0, 0
843+
prof.haveStack = false
838844

839845
rate := int64(atomic.Load64(&mutexprofilerate))
840846
saveBlockEventStack(cycles, rate, prof.stack[:nstk], mutexProfile)

src/runtime/pprof/pprof_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,7 @@ func TestMutexProfileRateAdjust(t *testing.T) {
13711371

13721372
blockMutex(t)
13731373
contentions, delay := readProfile()
1374-
if contentions == 0 || delay == 0 {
1374+
if contentions == 0 { // low-resolution timers can have delay of 0 in mutex profile
13751375
t.Fatal("did not see expected function in profile")
13761376
}
13771377
runtime.SetMutexProfileFraction(0)

0 commit comments

Comments
 (0)