Commit ab242dcb authored by Joel Sing's avatar Joel Sing

syscall: implement rawVforkSyscall for linux/ppc64x and linux/s390x

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.

The same problem was addressed on linux/amd64 via issue #5838.

Updates #31936

Change-Id: I7ae0fbbeaa29cab944a49a11272a380d497eb2d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/175697
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 38431f10
...@@ -102,6 +102,26 @@ ok2: ...@@ -102,6 +102,26 @@ ok2:
MOVD R0, err+72(FP) // errno MOVD R0, err+72(FP) // errno
RET RET
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVD a1+8(FP), R3
MOVD R0, R4
MOVD R0, R5
MOVD R0, R6
MOVD R0, R7
MOVD R0, R8
MOVD trap+0(FP), R9 // syscall entry
SYSCALL R9
BVC ok
MOVD $-1, R4
MOVD R4, r1+16(FP) // r1
MOVD R3, err+24(FP) // errno
RET
ok:
MOVD R3, r1+16(FP) // r1
MOVD R0, err+24(FP) // errno
RET
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R3 MOVD a1+8(FP), R3
MOVD a2+16(FP), R4 MOVD a2+16(FP), R4
......
...@@ -106,6 +106,27 @@ ok2: ...@@ -106,6 +106,27 @@ ok2:
MOVD $0, err+72(FP) // errno MOVD $0, err+72(FP) // errno
RET RET
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVD $0, R2
MOVD a1+8(FP), R3
MOVD $0, R4
MOVD $0, R5
MOVD $0, R6
MOVD $0, R7
MOVD trap+0(FP), R1 // syscall entry
SYSCALL
MOVD $0xfffffffffffff001, R8
CMPUBLT R2, R8, ok2
MOVD $-1, r1+16(FP)
NEG R2, R2
MOVD R2, err+24(FP) // errno
RET
ok2:
MOVD R2, r1+16(FP)
MOVD $0, err+24(FP) // errno
RET
// func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) // func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R2 MOVD a1+8(FP), R2
......
...@@ -196,12 +196,14 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att ...@@ -196,12 +196,14 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
} }
} }
hasRawVforkSyscall := runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "s390x"
// About to call fork. // About to call fork.
// No more allocation or calls of non-assembly functions. // No more allocation or calls of non-assembly functions.
runtime_BeforeFork() runtime_BeforeFork()
locked = true locked = true
switch { switch {
case runtime.GOARCH == "amd64" && (sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0): case hasRawVforkSyscall && (sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0):
r1, err1 = rawVforkSyscall(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags) r1, err1 = rawVforkSyscall(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags)
case runtime.GOARCH == "s390x": case runtime.GOARCH == "s390x":
r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0) r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)
......
...@@ -116,9 +116,7 @@ func (cmsg *Cmsghdr) SetLen(length int) { ...@@ -116,9 +116,7 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) { func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
panic("not implemented")
}
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2 //sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
......
...@@ -288,6 +288,4 @@ func (cmsg *Cmsghdr) SetLen(length int) { ...@@ -288,6 +288,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) { func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
panic("not implemented")
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment