aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2019-05-07 17:56:49 +1000
committerJoel Sing <joel@sing.id.au>2021-03-03 05:33:21 +0000
commit00cb841b83ad157bc21d36daf0626bbcd4af0d57 (patch)
tree10d3c992346b69236eb1356bfd381cc5e4f49584
parentf2df1e3c34ceb2225d0df5c9ec92d5dc9e9ba919 (diff)
downloadgo-00cb841b83ad157bc21d36daf0626bbcd4af0d57.tar.gz
go-00cb841b83ad157bc21d36daf0626bbcd4af0d57.zip
syscall: implement rawVforkSyscall for remaining linux platforms
This allows the use of CLONE_VFORK and CLONE_VM for fork/exec, preventing 'fork/exec ...: cannot allocate memory' failures from occuring when attempting to execute commands from a Go process that has a large memory footprint. Additionally, this should reduce the latency of fork/exec on these platforms. Fixes #31936 Change-Id: I4e28cf0763173145cacaa5340680dca9ff449305 Reviewed-on: https://go-review.googlesource.com/c/go/+/295849 Trust: Joel Sing <joel@sing.id.au> Run-TryBot: Joel Sing <joel@sing.id.au> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-rw-r--r--src/syscall/asm_linux_386.s20
-rw-r--r--src/syscall/asm_linux_amd64.s2
-rw-r--r--src/syscall/asm_linux_arm.s21
-rw-r--r--src/syscall/asm_linux_arm64.s1
-rw-r--r--src/syscall/asm_linux_mips64x.s20
-rw-r--r--src/syscall/asm_linux_mipsx.s17
-rw-r--r--src/syscall/exec_linux.go8
-rw-r--r--src/syscall/syscall_linux_386.go4
-rw-r--r--src/syscall/syscall_linux_arm.go4
-rw-r--r--src/syscall/syscall_linux_mips64x.go4
-rw-r--r--src/syscall/syscall_linux_mipsx.go4
11 files changed, 84 insertions, 21 deletions
diff --git a/src/syscall/asm_linux_386.s b/src/syscall/asm_linux_386.s
index 4201f367ba..1c69083118 100644
--- a/src/syscall/asm_linux_386.s
+++ b/src/syscall/asm_linux_386.s
@@ -110,6 +110,26 @@ ok2:
MOVL $0, err+36(FP)
RET
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+ MOVL trap+0(FP), AX // syscall entry
+ MOVL a1+4(FP), BX
+ MOVL $0, CX
+ MOVL $0, DX
+ POPL SI // preserve return address
+ INVOKE_SYSCALL
+ PUSHL SI
+ CMPL AX, $0xfffff001
+ JLS ok
+ MOVL $-1, r1+8(FP)
+ NEGL AX
+ MOVL AX, err+12(FP)
+ RET
+ok:
+ MOVL AX, r1+8(FP)
+ MOVL $0, err+12(FP)
+ RET
+
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
MOVL trap+0(FP), AX // syscall entry
diff --git a/src/syscall/asm_linux_amd64.s b/src/syscall/asm_linux_amd64.s
index ba22179dc2..a9af68d51d 100644
--- a/src/syscall/asm_linux_amd64.s
+++ b/src/syscall/asm_linux_amd64.s
@@ -108,7 +108,7 @@ ok2:
RET
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVQ a1+8(FP), DI
MOVQ $0, SI
MOVQ $0, DX
diff --git a/src/syscall/asm_linux_arm.s b/src/syscall/asm_linux_arm.s
index 458e9cce79..6bb4df81a0 100644
--- a/src/syscall/asm_linux_arm.s
+++ b/src/syscall/asm_linux_arm.s
@@ -154,6 +154,27 @@ ok1:
MOVW R0, err+24(FP)
RET
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+ MOVW trap+0(FP), R7 // syscall entry
+ MOVW a1+4(FP), R0
+ MOVW $0, R1
+ MOVW $0, R2
+ SWI $0
+ MOVW $0xfffff001, R1
+ CMP R1, R0
+ BLS ok
+ MOVW $-1, R1
+ MOVW R1, r1+8(FP)
+ RSB $0, R0, R0
+ MOVW R0, err+12(FP)
+ RET
+ok:
+ MOVW R0, r1+8(FP)
+ MOVW $0, R0
+ MOVW R0, err+12(FP)
+ RET
+
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
MOVW trap+0(FP), R7 // syscall entry
diff --git a/src/syscall/asm_linux_arm64.s b/src/syscall/asm_linux_arm64.s
index fb22f8d547..a30e4d87d4 100644
--- a/src/syscall/asm_linux_arm64.s
+++ b/src/syscall/asm_linux_arm64.s
@@ -125,7 +125,6 @@ ok:
MOVD ZR, err+24(FP) // errno
RET
-
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R0
diff --git a/src/syscall/asm_linux_mips64x.s b/src/syscall/asm_linux_mips64x.s
index d0b0e5a0a8..b3ae59023d 100644
--- a/src/syscall/asm_linux_mips64x.s
+++ b/src/syscall/asm_linux_mips64x.s
@@ -102,6 +102,26 @@ ok2:
MOVV R0, err+72(FP) // errno
RET
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
+ MOVV a1+8(FP), R4
+ MOVV R0, R5
+ MOVV R0, R6
+ MOVV R0, R7
+ MOVV R0, R8
+ MOVV R0, R9
+ MOVV trap+0(FP), R2 // syscall entry
+ SYSCALL
+ BEQ R7, ok
+ MOVV $-1, R1
+ MOVV R1, r1+16(FP) // r1
+ MOVV R2, err+24(FP) // errno
+ RET
+ok:
+ MOVV R2, r1+16(FP) // r1
+ MOVV R0, err+24(FP) // errno
+ RET
+
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVV a1+8(FP), R4
MOVV a2+16(FP), R5
diff --git a/src/syscall/asm_linux_mipsx.s b/src/syscall/asm_linux_mipsx.s
index 5727e4d41d..ee436490b2 100644
--- a/src/syscall/asm_linux_mipsx.s
+++ b/src/syscall/asm_linux_mipsx.s
@@ -139,6 +139,23 @@ ok2:
MOVW R0, err+36(FP) // errno
RET
+// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+ MOVW a1+4(FP), R4
+ MOVW R0, R5
+ MOVW R0, R6
+ MOVW trap+0(FP), R2 // syscall entry
+ SYSCALL
+ BEQ R7, ok
+ MOVW $-1, R1
+ MOVW R1, r1+8(FP) // r1
+ MOVW R2, err+12(FP) // errno
+ RET
+ok:
+ MOVW R2, r1+8(FP) // r1
+ MOVW R0, err+12(FP) // errno
+ RET
+
TEXT ·rawSyscallNoError(SB),NOSPLIT,$20-24
MOVW a1+4(FP), R4
MOVW a2+8(FP), R5
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index b0099cb4b0..6353da4048 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -208,18 +208,12 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
}
}
- var hasRawVforkSyscall bool
- switch runtime.GOARCH {
- case "amd64", "arm64", "ppc64", "riscv64", "s390x":
- hasRawVforkSyscall = true
- }
-
// About to call fork.
// No more allocation or calls of non-assembly functions.
runtime_BeforeFork()
locked = true
switch {
- case hasRawVforkSyscall && (sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0):
+ case sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0:
r1, err1 = rawVforkSyscall(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags)
case runtime.GOARCH == "s390x":
r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)
diff --git a/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
index ed52647403..0db037470d 100644
--- a/src/syscall/syscall_linux_386.go
+++ b/src/syscall/syscall_linux_386.go
@@ -387,6 +387,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
- panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index 4a3729f898..e887cf788f 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -236,6 +236,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
- panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_mips64x.go b/src/syscall/syscall_linux_mips64x.go
index dd51f3d00a..5feb03e915 100644
--- a/src/syscall/syscall_linux_mips64x.go
+++ b/src/syscall/syscall_linux_mips64x.go
@@ -214,6 +214,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
- panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_mipsx.go b/src/syscall/syscall_linux_mipsx.go
index 7894bdd465..39104d71d8 100644
--- a/src/syscall/syscall_linux_mipsx.go
+++ b/src/syscall/syscall_linux_mipsx.go
@@ -224,6 +224,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
- panic("not implemented")
-}
+func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)