Skip to content

Commit dbd8af7

Browse files
ceseolaboger
authored andcommitted
runtime: add support for VDSO on ppc64x for use in walltime/nanotime
This change adds support for VDSO on ppc64x, making it possible to avoid a syscall in walltime and nanotime. BenchmarkClockVDSOAndFallbackPaths/vDSO-192 20000000 66.0 ns/op BenchmarkClockVDSOAndFallbackPaths/Fallback-192 1000000 1456 ns/op Change-Id: I3373bd804b6f122961de3ae9d034e6ccf35748e6 Reviewed-on: https://go-review.googlesource.com/131135 Run-TryBot: Lynn Boger <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Lynn Boger <[email protected]>
1 parent 8359b5e commit dbd8af7

7 files changed

+118
-16
lines changed

src/runtime/os_linux_novdso.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build !386,!amd64,!arm,!arm64
6+
// +build !386,!amd64,!arm,!arm64,!ppc64,!ppc64le
77

88
package runtime
99

src/runtime/sys_linux_ppc64x.s

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,21 +154,87 @@ TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
154154

155155
// func walltime() (sec int64, nsec int32)
156156
TEXT runtime·walltime(SB),NOSPLIT,$16
157-
MOVD $0, R3 // CLOCK_REALTIME
158-
MOVD $0(R1), R4
159-
SYSCALL $SYS_clock_gettime
160-
MOVD 0(R1), R3 // sec
161-
MOVD 8(R1), R5 // nsec
157+
MOVD R1, R15 // R15 is unchanged by C code
158+
MOVD g_m(g), R21 // R21 = m
159+
160+
MOVD $0, R3 // CLOCK_REALTIME
161+
162+
MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability
163+
CMP R12, R0
164+
BEQ fallback
165+
166+
// Set vdsoPC and vdsoSP for SIGPROF traceback.
167+
MOVD LR, R14
168+
MOVD R14, m_vdsoPC(R21)
169+
MOVD R15, m_vdsoSP(R21)
170+
171+
MOVD m_curg(R21), R6
172+
CMP g, R6
173+
BNE noswitch
174+
175+
MOVD m_g0(R21), R7
176+
MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
177+
178+
noswitch:
179+
SUB $16, R1 // Space for results
180+
RLDICR $0, R1, $59, R1 // Align for C code
181+
MOVD R12, CTR
182+
MOVD R1, R4
183+
BL (CTR) // Call from VDSO
184+
MOVD $0, R0 // Restore R0
185+
MOVD R0, m_vdsoSP(R21) // Clear vdsoSP
186+
MOVD 0(R1), R3 // sec
187+
MOVD 8(R1), R5 // nsec
188+
MOVD R15, R1 // Restore SP
189+
190+
finish:
162191
MOVD R3, sec+0(FP)
163192
MOVW R5, nsec+8(FP)
164193
RET
165194

195+
// Syscall fallback
196+
fallback:
197+
ADD $32, R1, R4
198+
SYSCALL $SYS_clock_gettime
199+
MOVD 32(R1), R3
200+
MOVD 40(R1), R5
201+
JMP finish
202+
166203
TEXT runtime·nanotime(SB),NOSPLIT,$16
167-
MOVW $1, R3 // CLOCK_MONOTONIC
168-
MOVD $0(R1), R4
169-
SYSCALL $SYS_clock_gettime
170-
MOVD 0(R1), R3 // sec
171-
MOVD 8(R1), R5 // nsec
204+
MOVD $1, R3 // CLOCK_MONOTONIC
205+
206+
MOVD R1, R15 // R15 is unchanged by C code
207+
MOVD g_m(g), R21 // R21 = m
208+
209+
MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability
210+
CMP R12, R0
211+
BEQ fallback
212+
213+
// Set vdsoPC and vdsoSP for SIGPROF traceback.
214+
MOVD LR, R14 // R14 is unchanged by C code
215+
MOVD R14, m_vdsoPC(R21)
216+
MOVD R15, m_vdsoSP(R21)
217+
218+
MOVD m_curg(R21), R6
219+
CMP g, R6
220+
BNE noswitch
221+
222+
MOVD m_g0(R21), R7
223+
MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack
224+
225+
noswitch:
226+
SUB $16, R1 // Space for results
227+
RLDICR $0, R1, $59, R1 // Align for C code
228+
MOVD R12, CTR
229+
MOVD R1, R4
230+
BL (CTR) // Call from VDSO
231+
MOVD $0, R0 // Restore R0
232+
MOVD $0, m_vdsoSP(R21) // Clear vdsoSP
233+
MOVD 0(R1), R3 // sec
234+
MOVD 8(R1), R5 // nsec
235+
MOVD R15, R1 // Restore SP
236+
237+
finish:
172238
// sec is in R3, nsec in R5
173239
// return nsec in R3
174240
MOVD $1000000000, R4
@@ -177,6 +243,14 @@ TEXT runtime·nanotime(SB),NOSPLIT,$16
177243
MOVD R3, ret+0(FP)
178244
RET
179245

246+
// Syscall fallback
247+
fallback:
248+
ADD $32, R1, R4
249+
SYSCALL $SYS_clock_gettime
250+
MOVD 32(R1), R3
251+
MOVD 48(R1), R5
252+
JMP finish
253+
180254
TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
181255
MOVW how+0(FP), R3
182256
MOVD new+8(FP), R4

src/runtime/vdso_elf64.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build amd64 arm64
6+
// +build amd64 arm64 ppc64 ppc64le
77

88
package runtime
99

src/runtime/vdso_in_none.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build linux,!386,!amd64,!arm,!arm64 !linux
5+
// +build linux,!386,!amd64,!arm,!arm64,!ppc64,!ppc64le !linux
66

77
package runtime
88

src/runtime/vdso_linux.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build 386 amd64 arm arm64
6+
// +build 386 amd64 arm arm64 ppc64 ppc64le
77

88
package runtime
99

@@ -42,6 +42,8 @@ const (
4242

4343
_STT_FUNC = 2 /* Symbol is a code object */
4444

45+
_STT_NOTYPE = 0 /* Symbol type is not specified */
46+
4547
_STB_GLOBAL = 1 /* Global symbol */
4648
_STB_WEAK = 2 /* Weak symbol */
4749

@@ -212,7 +214,8 @@ func vdsoParseSymbols(info *vdsoInfo, version int32) {
212214
sym := &info.symtab[symIndex]
213215
typ := _ELF_ST_TYPE(sym.st_info)
214216
bind := _ELF_ST_BIND(sym.st_info)
215-
if typ != _STT_FUNC || bind != _STB_GLOBAL && bind != _STB_WEAK || sym.st_shndx == _SHN_UNDEF {
217+
// On ppc64x, VDSO functions are of type _STT_NOTYPE.
218+
if typ != _STT_FUNC && typ != _STT_NOTYPE || bind != _STB_GLOBAL && bind != _STB_WEAK || sym.st_shndx == _SHN_UNDEF {
216219
return false
217220
}
218221
if k.name != gostringnocopy(&info.symstrings[sym.st_name]) {

src/runtime/vdso_linux_ppc64x.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build linux
6+
// +build ppc64 ppc64le
7+
8+
package runtime
9+
10+
const (
11+
// vdsoArrayMax is the byte-size of a maximally sized array on this architecture.
12+
// See cmd/compile/internal/ppc64/galign.go arch.MAXWIDTH initialization.
13+
vdsoArrayMax = 1<<50 - 1
14+
)
15+
16+
var vdsoLinuxVersion = vdsoVersionKey{"LINUX_2.6.15", 0x75fcba5}
17+
18+
var vdsoSymbolKeys = []vdsoSymbolKey{
19+
{"__kernel_clock_gettime", 0xb0cd725, 0xdfa941fd, &vdsoClockgettimeSym},
20+
}
21+
22+
// initialize with vsyscall fallbacks
23+
var (
24+
vdsoClockgettimeSym uintptr = 0
25+
)

src/runtime/vdso_linux_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
// +build linux
6-
// +build 386 amd64 arm arm64
6+
// +build 386 amd64 arm arm64 ppc64 ppc64le
77

88
package runtime_test
99

0 commit comments

Comments
 (0)