aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_darwin.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2019-11-19 12:41:51 -0800
committerDan Scales <danscales@google.com>2019-11-25 03:41:16 +0000
commit9940c7768261f035b14657053ada8d0e88283241 (patch)
treeae5dcc4fc4ea6cdf495f24755336fe1e6cdae945 /src/runtime/sys_darwin.go
parentb81dd1c0e722a7d048ffe935d3f2062d2fae4e86 (diff)
downloadgo-9940c7768261f035b14657053ada8d0e88283241.tar.gz
go-9940c7768261f035b14657053ada8d0e88283241.zip
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 <iant@golang.org>
Diffstat (limited to 'src/runtime/sys_darwin.go')
-rw-r--r--src/runtime/sys_darwin.go4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index 31304ce737..d2d1822aab 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -170,6 +170,10 @@ func pthread_kill(t pthread, sig uint32) {
}
func pthread_kill_trampoline()
+// mmap is used to do low-level memory allocation via mmap. Don't allow stack
+// splits, since this function (used by sysAlloc) is called in a lot of low-level
+// parts of the runtime and callers often assume it won't acquire any locks.
+// go:nosplit
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
args := struct {
addr unsafe.Pointer