]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: implement rawVforkSyscall for linux/ppc64x and linux/s390x
authorJoel Sing <joel@sing.id.au>
Tue, 7 May 2019 07:56:49 +0000 (17:56 +1000)
committerJoel Sing <joel@sing.id.au>
Wed, 15 May 2019 18:12:10 +0000 (18:12 +0000)
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: Ian Lance Taylor <iant@golang.org>
src/syscall/asm_linux_ppc64x.s
src/syscall/asm_linux_s390x.s
src/syscall/exec_linux.go
src/syscall/syscall_linux_ppc64x.go
src/syscall/syscall_linux_s390x.go

index 424efbbdc98b5b4a811af2241fae9aece88a306e..8be0d68d707670fc5b970a6b2941917ec0794a42 100644 (file)
@@ -102,6 +102,26 @@ ok2:
        MOVD    R0, err+72(FP)  // errno
        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
        MOVD    a1+8(FP), R3
        MOVD    a2+16(FP), R4
index 62125f261027dc08613eff7e6ee255da9e35a48c..86a5c51ee29dfb7093dc6ffcb3fa71c594973e8c 100644 (file)
@@ -106,6 +106,27 @@ ok2:
        MOVD    $0, err+72(FP)  // errno
        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)
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
        MOVD    a1+8(FP), R2
index 3493f4b32b85f8c79b26987e9e17aed3a2f40e2e..a2242b2057cc3cc9d21865fe4282f957bb089ca5 100644 (file)
@@ -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.
        // No more allocation or calls of non-assembly functions.
        runtime_BeforeFork()
        locked = true
        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)
        case runtime.GOARCH == "s390x":
                r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)
index 1cdc5f9a44155fd9a18d5fa2013f099e4f1810ef..47d8820ba6aed83efb5c27d3adc4e9d0dae65d39 100644 (file)
@@ -116,9 +116,7 @@ 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)
 
 //sys  syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
 
index e53b63c6a406ea8f4be2d22a699ec522a36295ce..c6d71c492aa9e773d3f80edbe58a2ce38f5d4c4f 100644 (file)
@@ -288,6 +288,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)