Skip to content

Commit 00cb841

Browse files
committed
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>
1 parent f2df1e3 commit 00cb841

11 files changed

+84
-21
lines changed

src/syscall/asm_linux_386.s

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,26 @@ ok2:
110110
MOVL $0, err+36(FP)
111111
RET
112112

113+
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
114+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
115+
MOVL trap+0(FP), AX // syscall entry
116+
MOVL a1+4(FP), BX
117+
MOVL $0, CX
118+
MOVL $0, DX
119+
POPL SI // preserve return address
120+
INVOKE_SYSCALL
121+
PUSHL SI
122+
CMPL AX, $0xfffff001
123+
JLS ok
124+
MOVL $-1, r1+8(FP)
125+
NEGL AX
126+
MOVL AX, err+12(FP)
127+
RET
128+
ok:
129+
MOVL AX, r1+8(FP)
130+
MOVL $0, err+12(FP)
131+
RET
132+
113133
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
114134
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
115135
MOVL trap+0(FP), AX // syscall entry

src/syscall/asm_linux_amd64.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ ok2:
108108
RET
109109

110110
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
111-
TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
111+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
112112
MOVQ a1+8(FP), DI
113113
MOVQ $0, SI
114114
MOVQ $0, DX

src/syscall/asm_linux_arm.s

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,27 @@ ok1:
154154
MOVW R0, err+24(FP)
155155
RET
156156

157+
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
158+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
159+
MOVW trap+0(FP), R7 // syscall entry
160+
MOVW a1+4(FP), R0
161+
MOVW $0, R1
162+
MOVW $0, R2
163+
SWI $0
164+
MOVW $0xfffff001, R1
165+
CMP R1, R0
166+
BLS ok
167+
MOVW $-1, R1
168+
MOVW R1, r1+8(FP)
169+
RSB $0, R0, R0
170+
MOVW R0, err+12(FP)
171+
RET
172+
ok:
173+
MOVW R0, r1+8(FP)
174+
MOVW $0, R0
175+
MOVW R0, err+12(FP)
176+
RET
177+
157178
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
158179
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-24
159180
MOVW trap+0(FP), R7 // syscall entry

src/syscall/asm_linux_arm64.s

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ ok:
125125
MOVD ZR, err+24(FP) // errno
126126
RET
127127

128-
129128
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
130129
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
131130
MOVD a1+8(FP), R0

src/syscall/asm_linux_mips64x.s

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,26 @@ ok2:
102102
MOVV R0, err+72(FP) // errno
103103
RET
104104

105+
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
106+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
107+
MOVV a1+8(FP), R4
108+
MOVV R0, R5
109+
MOVV R0, R6
110+
MOVV R0, R7
111+
MOVV R0, R8
112+
MOVV R0, R9
113+
MOVV trap+0(FP), R2 // syscall entry
114+
SYSCALL
115+
BEQ R7, ok
116+
MOVV $-1, R1
117+
MOVV R1, r1+16(FP) // r1
118+
MOVV R2, err+24(FP) // errno
119+
RET
120+
ok:
121+
MOVV R2, r1+16(FP) // r1
122+
MOVV R0, err+24(FP) // errno
123+
RET
124+
105125
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
106126
MOVV a1+8(FP), R4
107127
MOVV a2+16(FP), R5

src/syscall/asm_linux_mipsx.s

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,23 @@ ok2:
139139
MOVW R0, err+36(FP) // errno
140140
RET
141141

142+
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
143+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
144+
MOVW a1+4(FP), R4
145+
MOVW R0, R5
146+
MOVW R0, R6
147+
MOVW trap+0(FP), R2 // syscall entry
148+
SYSCALL
149+
BEQ R7, ok
150+
MOVW $-1, R1
151+
MOVW R1, r1+8(FP) // r1
152+
MOVW R2, err+12(FP) // errno
153+
RET
154+
ok:
155+
MOVW R2, r1+8(FP) // r1
156+
MOVW R0, err+12(FP) // errno
157+
RET
158+
142159
TEXT ·rawSyscallNoError(SB),NOSPLIT,$20-24
143160
MOVW a1+4(FP), R4
144161
MOVW a2+8(FP), R5

src/syscall/exec_linux.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,18 +208,12 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
208208
}
209209
}
210210

211-
var hasRawVforkSyscall bool
212-
switch runtime.GOARCH {
213-
case "amd64", "arm64", "ppc64", "riscv64", "s390x":
214-
hasRawVforkSyscall = true
215-
}
216-
217211
// About to call fork.
218212
// No more allocation or calls of non-assembly functions.
219213
runtime_BeforeFork()
220214
locked = true
221215
switch {
222-
case hasRawVforkSyscall && (sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0):
216+
case sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0:
223217
r1, err1 = rawVforkSyscall(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags)
224218
case runtime.GOARCH == "s390x":
225219
r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)

src/syscall/syscall_linux_386.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
387387
cmsg.Len = uint32(length)
388388
}
389389

390-
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
391-
panic("not implemented")
392-
}
390+
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)

src/syscall/syscall_linux_arm.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
236236
cmsg.Len = uint32(length)
237237
}
238238

239-
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
240-
panic("not implemented")
241-
}
239+
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)

src/syscall/syscall_linux_mips64x.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
214214
cmsg.Len = uint64(length)
215215
}
216216

217-
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
218-
panic("not implemented")
219-
}
217+
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)

src/syscall/syscall_linux_mipsx.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,4 @@ func (cmsg *Cmsghdr) SetLen(length int) {
224224
cmsg.Len = uint32(length)
225225
}
226226

227-
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
228-
panic("not implemented")
229-
}
227+
func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)

0 commit comments

Comments
 (0)