Skip to content

Commit 9940c77

Browse files
committed
runtime: add go:nosplit to cgo_mmap.go:mmap() and sys_darwin.go:mmap()
cgo_mmap.go:mmap() is called by mem_linux.go:sysAlloc(), a low-level memory allocation function. mmap() should be nosplit, since it is called in a lot of low-level parts of the runtime and callers often assume it won't acquire any locks. As an example there is a potential deadlock involving two threads if mmap is not nosplit: trace.bufLock acquired, then stackpool[order].item.mu, then mheap_.lock - can happen for traceEvents that are not invoked on the system stack and cause a traceFlush, which causes a sysAlloc, which calls mmap(), which may cause a stack split. mheap_.lock mheap_.lock acquired, then trace.bufLock - can happen when doing a trace in reclaimChunk (which holds the mheap_ lock) Also, sysAlloc() has a comment that it is nosplit because it may be invoked without a valid G, in which case its callee mmap() should also be nosplit. Similarly, sys_darwin.go:mmap() is called by mem_darwin.go:sysAlloc(), and should be nosplit for the same reasons. Extra gomote testing: linux/arm64, darwin/amd64 Change-Id: Ia4d10cec5cf1e186a0fe5aab2858c6e0e5b80fdc Reviewed-on: https://go-review.googlesource.com/c/go/+/207844 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent b81dd1c commit 9940c77

File tree

2 files changed

+9
-0
lines changed

2 files changed

+9
-0
lines changed

src/runtime/cgo_mmap.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ var _cgo_mmap unsafe.Pointer
2020
//go:linkname _cgo_munmap _cgo_munmap
2121
var _cgo_munmap unsafe.Pointer
2222

23+
// mmap is used to route the mmap system call through C code when using cgo, to
24+
// support sanitizer interceptors. Don't allow stack splits, since this function
25+
// (used by sysAlloc) is called in a lot of low-level parts of the runtime and
26+
// callers often assume it won't acquire any locks.
27+
//go:nosplit
2328
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
2429
if _cgo_mmap != nil {
2530
// Make ret a uintptr so that writing to it in the

src/runtime/sys_darwin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ func pthread_kill(t pthread, sig uint32) {
170170
}
171171
func pthread_kill_trampoline()
172172

173+
// mmap is used to do low-level memory allocation via mmap. Don't allow stack
174+
// splits, since this function (used by sysAlloc) is called in a lot of low-level
175+
// parts of the runtime and callers often assume it won't acquire any locks.
176+
// go:nosplit
173177
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
174178
args := struct {
175179
addr unsafe.Pointer

0 commit comments

Comments
 (0)