From: Austin Clements Date: Mon, 22 Aug 2022 20:14:34 +0000 (-0400) Subject: runtime: move traceStackTable.lock to the system stack X-Git-Tag: go1.20rc1~1469 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=42794f3871c35d1b3837f78f29d781b6ab1c1a64;p=gostls13.git runtime: move traceStackTable.lock to the system stack This lock is acquired under trace.lock, which as of CL 418956 (6c2e327e35b) must be acquired on the system stack, so this lock must be, too. Fixes #54553. Change-Id: I4fb0c0c2dfc3cb94b76673e842ad416305a31238 Reviewed-on: https://go-review.googlesource.com/c/go/+/425097 Reviewed-by: Michael Knyszek TryBot-Result: Gopher Robot Run-TryBot: Austin Clements Reviewed-by: Michael Pratt --- diff --git a/src/runtime/trace.go b/src/runtime/trace.go index 927a66d161..ab6402c706 100644 --- a/src/runtime/trace.go +++ b/src/runtime/trace.go @@ -1054,7 +1054,7 @@ func (buf *traceBuf) byte(v byte) { // traceStackTable maps stack traces (arrays of PC's) to unique uint32 ids. // It is lock-free for reading. type traceStackTable struct { - lock mutex + lock mutex // Must be acquired on the system stack seq uint32 mem traceAlloc tab [1 << 13]traceStackPtr @@ -1090,26 +1090,31 @@ func (tab *traceStackTable) put(pcs []uintptr) uint32 { return id } // Now, double check under the mutex. - lock(&tab.lock) - if id := tab.find(pcs, hash); id != 0 { + // Switch to the system stack so we can acquire tab.lock + var id uint32 + systemstack(func() { + lock(&tab.lock) + if id = tab.find(pcs, hash); id != 0 { + unlock(&tab.lock) + return + } + // Create new record. + tab.seq++ + stk := tab.newStack(len(pcs)) + stk.hash = hash + stk.id = tab.seq + id = stk.id + stk.n = len(pcs) + stkpc := stk.stack() + for i, pc := range pcs { + stkpc[i] = pc + } + part := int(hash % uintptr(len(tab.tab))) + stk.link = tab.tab[part] + atomicstorep(unsafe.Pointer(&tab.tab[part]), unsafe.Pointer(stk)) unlock(&tab.lock) - return id - } - // Create new record. - tab.seq++ - stk := tab.newStack(len(pcs)) - stk.hash = hash - stk.id = tab.seq - stk.n = len(pcs) - stkpc := stk.stack() - for i, pc := range pcs { - stkpc[i] = pc - } - part := int(hash % uintptr(len(tab.tab))) - stk.link = tab.tab[part] - atomicstorep(unsafe.Pointer(&tab.tab[part]), unsafe.Pointer(stk)) - unlock(&tab.lock) - return stk.id + }) + return id } // find checks if the stack trace pcs is already present in the table.