1
0
mirror of https://github.com/golang/go synced 2024-11-26 18:26:48 -07:00

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>
This commit is contained in:
Joel Sing 2019-05-07 17:56:49 +10:00
parent f2df1e3c34
commit 00cb841b83
11 changed files with 84 additions and 21 deletions

View File

@ -110,6 +110,26 @@ ok2:
MOVL $0, err+36(FP) MOVL $0, err+36(FP)
RET 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); // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
MOVL trap+0(FP), AX // syscall entry MOVL trap+0(FP), AX // syscall entry

View File

@ -108,7 +108,7 @@ ok2:
RET RET
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr) // 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 a1+8(FP), DI
MOVQ $0, SI MOVQ $0, SI
MOVQ $0, DX MOVQ $0, DX

View File

@ -154,6 +154,27 @@ ok1:
MOVW R0, err+24(FP) MOVW R0, err+24(FP)
RET 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); // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
MOVW trap+0(FP), R7 // syscall entry MOVW trap+0(FP), R7 // syscall entry

View File

@ -125,7 +125,6 @@ ok:
MOVD ZR, err+24(FP) // errno MOVD ZR, err+24(FP) // errno
RET RET
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr); // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R0 MOVD a1+8(FP), R0

View File

@ -102,6 +102,26 @@ ok2:
MOVV R0, err+72(FP) // errno MOVV R0, err+72(FP) // errno
RET 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 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVV a1+8(FP), R4 MOVV a1+8(FP), R4
MOVV a2+16(FP), R5 MOVV a2+16(FP), R5

View File

@ -139,6 +139,23 @@ ok2:
MOVW R0, err+36(FP) // errno MOVW R0, err+36(FP) // errno
RET 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 TEXT ·rawSyscallNoError(SB),NOSPLIT,$20-24
MOVW a1+4(FP), R4 MOVW a1+4(FP), R4
MOVW a2+8(FP), R5 MOVW a2+8(FP), R5

View File

@ -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. // 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 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) 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)

View File

@ -387,6 +387,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) { func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
panic("not implemented")
}

View File

@ -236,6 +236,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) { func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
panic("not implemented")
}

View File

@ -214,6 +214,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")
}

View File

@ -224,6 +224,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) { func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
panic("not implemented")
}