Skip to content

Commit afae876

Browse files
philhofercherrymui
authored andcommitted
runtime: fix pprof livelock on arm
On 32-bit architectures without native 64-bit atomic instructions, 64-bit atomics are emulated using spinlocks. However, the sigprof handling code expects to be able to perform 64-bit atomic operations in signal handlers. Spinning on an acquired spinlock in a signal handler leads to a livelock. This is issue #20146. The original fix for #20146 did not include arm in the list of architectures that need to work around portability issues in the sigprof handler code. The unit test designed to catch this issue does not fail on arm builds because arm uses striped spinlocks, and thus the livelock takes many minutes to reproduce. This is issue #24260. (This patch doesn't completely fix #24260 on go1.10.2 due to issue #25785, which is probably related to the arm cas kernel helpers. Those have been removed at tip.) With this patch applied, I was able to run the reproducer for issue #24260 for more than 90 minutes without reproducing the livelock. Without this patch, the livelock took as little as 8 minutes to reproduce. Fixes #20146 Updates #24260 Change-Id: I64bf53a14d53c4932367d919ac55e17c99d87484 Reviewed-on: https://go-review.googlesource.com/117057 Run-TryBot: Philip Hofer <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent abeac09 commit afae876

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

src/runtime/proc.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -3699,7 +3699,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
36993699
// As a workaround, create a counter of SIGPROFs while in critical section
37003700
// to store the count, and pass it to sigprof.add() later when SIGPROF is
37013701
// received from somewhere else (with _LostSIGPROFDuringAtomic64 as pc).
3702-
if GOARCH == "mips" || GOARCH == "mipsle" {
3702+
if GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "arm" {
37033703
if f := findfunc(pc); f.valid() {
37043704
if hasprefix(funcname(f), "runtime/internal/atomic") {
37053705
lostAtomic64Count++
@@ -3839,7 +3839,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
38393839
}
38403840

38413841
if prof.hz != 0 {
3842-
if (GOARCH == "mips" || GOARCH == "mipsle") && lostAtomic64Count > 0 {
3842+
if (GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "arm") && lostAtomic64Count > 0 {
38433843
cpuprof.addLostAtomic64(lostAtomic64Count)
38443844
lostAtomic64Count = 0
38453845
}

0 commit comments

Comments
 (0)