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

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