Gerrit Bot has uploaded this change for review.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: b5e3b2d9f35ffc6fc22168ad3c61bce2f0563b1f
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/vdso_elf64.go
A src/runtime/vdso_linux_s390x.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_linux.go
M src/runtime/os_linux_novdso.go
M src/runtime/vdso_in_none.go
6 files changed, 177 insertions(+), 26 deletions(-)
diff --git a/src/runtime/os_linux_novdso.go b/src/runtime/os_linux_novdso.go
index b06716d..1882b90 100644
--- a/src/runtime/os_linux_novdso.go
+++ b/src/runtime/os_linux_novdso.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64
+//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x
package runtime
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index 886add8..f72c2ce 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -224,29 +224,135 @@
RET
// func walltime() (sec int64, nsec int32)
-TEXT runtime·walltime(SB),NOSPLIT,$16
- MOVW $0, R2 // CLOCK_REALTIME
- MOVD $tp-16(SP), R3
- MOVW $SYS_clock_gettime, R1
- SYSCALL
- LMG tp-16(SP), R2, R3
- // sec is in R2, nsec in R3
- MOVD R2, sec+0(FP)
- MOVW R3, nsec+8(FP)
- RET
+TEXT runtime·walltime(SB),NOSPLIT,$16-12
+ MOVW $0, R2 // CLOCK_REALTIME
+ MOVD R15, R7 // Backup stack pointer
-TEXT runtime·nanotime1(SB),NOSPLIT,$16
- MOVW $1, R2 // CLOCK_MONOTONIC
- MOVD $tp-16(SP), R3
- MOVW $SYS_clock_gettime, R1
- SYSCALL
- LMG tp-16(SP), R2, R3
- // sec is in R2, nsec in R3
- // return nsec in R2
- MULLD $1000000000, R2
- ADD R3, R2
- MOVD R2, ret+0(FP)
- RET
+ MOVD g_m(g), R10 //m
+
+ MOVD runtime·vdsoClockgettimeSym(SB), R9 // Check for VDSO availability
+ CMPBEQ R9, $0, fallback
+
+ MOVD m_vdsoPC(R10), R6
+ MOVD m_vdsoSP(R10), R12
+
+ MOVD R14, R8 // Backup LR
+ MOVD $sec+0(FP), R4 // caller's SP
+
+ MOVD R8, m_vdsoPC(R10)
+ MOVD R4, m_vdsoSP(R10)
+
+ MOVD m_curg(R10), R5
+ CMP g, R5
+ BNE noswitch
+
+ MOVD m_g0(R10), R4
+ MOVD (g_sched+gobuf_sp)(R4), R15 // Set SP to g0 stack
+
+noswitch:
+ SUB $16, R15 // reserve 2x 8 bytes for parameters
+ MOVD $~7, R4 // align to 8 bytes because of gcc ABI
+ AND R4, R15
+ MOVD R15, R3 // R15 needs to be in R3 as expected by kernel_clock_gettime
+
+ BL R9 // to vdso lookup
+
+finish:
+ MOVD 0(R15), R3 // sec
+ MOVD 8(R15), R5 // nsec
+ MOVD R7, R15 // Restore SP
+
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVD R12, m_vdsoSP(R10)
+ MOVD R6, m_vdsoPC(R10)
+
+return:
+ // sec is in R3, nsec in R5
+ // return nsec in R3
+ MOVD R3, sec+0(FP)
+ MOVW R5, nsec+8(FP)
+ RET
+
+ // Syscall fallback
+fallback:
+ MOVD $tp-16(SP), R3
+ MOVW $SYS_clock_gettime, R1
+ SYSCALL
+ LMG tp-16(SP), R2, R3
+ // sec is in R2, nsec in R3
+ MOVD R2, sec+0(FP)
+ MOVW R3, nsec+8(FP)
+ RET
+
+TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
+ MOVW $1, R2 // CLOCK_MONOTONIC
+
+ MOVD R15, R7 // Backup stack pointer
+
+ MOVD g_m(g), R10 //m
+
+ MOVD runtime·vdsoClockgettimeSym(SB), R9 // Check for VDSO availability
+ CMPBEQ R9, $0, fallback
+
+ MOVD m_vdsoPC(R10), R6
+ MOVD m_vdsoSP(R10), R12
+
+ MOVD R14, R8 // Backup LR
+ MOVD $ret+0(FP), R4 // caller's SP
+
+ MOVD R8, m_vdsoPC(R10)
+ MOVD R4, m_vdsoSP(R10)
+
+ MOVD m_curg(R10), R5
+ CMP g, R5
+ BNE noswitch
+
+ MOVD m_g0(R10), R4
+ MOVD (g_sched+gobuf_sp)(R4), R15 // Set SP to g0 stack
+
+noswitch:
+ SUB $16, R15 // reserve 2x 8 bytes for parameters
+ MOVD $~7, R4 // align to 8 bytes because of gcc ABI
+ AND R4, R15
+ MOVD R15, R3 // R15 needs to be in R3 as expected by kernel_clock_gettime
+
+ BL R9 // to vdso lookup
+
+finish:
+ MOVD 0(R15), R3 // sec
+ MOVD 8(R15), R5 // nsec
+ MOVD R7, R15 // Restore SP
+
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+
+ MOVD R12, m_vdsoSP(R10)
+ MOVD R6, m_vdsoPC(R10)
+
+return:
+ // sec is in R3, nsec in R5
+ // return nsec in R3
+ MULLD $1000000000, R3
+ ADD R5, R3
+ MOVD R3, ret+0(FP)
+ RET
+
+ // Syscall fallback
+fallback:
+ MOVD $tp-16(SP), R3
+ MOVD $SYS_clock_gettime, R1
+ SYSCALL
+ LMG tp-16(SP), R2, R3
+ MOVD R3, R5
+ MOVD R2, R3
+ JMP return
TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
MOVW how+0(FP), R2
diff --git a/src/runtime/vdso_elf64.go b/src/runtime/vdso_elf64.go
index d46d6f8..b50e58f 100644
--- a/src/runtime/vdso_elf64.go
+++ b/src/runtime/vdso_elf64.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && (amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64)
+//go:build linux && (amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x)
package runtime
diff --git a/src/runtime/vdso_in_none.go b/src/runtime/vdso_in_none.go
index 618bd39..a11ecb0 100644
--- a/src/runtime/vdso_in_none.go
+++ b/src/runtime/vdso_in_none.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64) || !linux
+//go:build (linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x) || !linux
package runtime
diff --git a/src/runtime/vdso_linux.go b/src/runtime/vdso_linux.go
index cff2000..61a5207 100644
--- a/src/runtime/vdso_linux.go
+++ b/src/runtime/vdso_linux.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && (386 || amd64 || arm || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64)
+//go:build linux && (386 || amd64 || arm || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x)
package runtime
diff --git a/src/runtime/vdso_linux_s390x.go b/src/runtime/vdso_linux_s390x.go
new file mode 100644
index 0000000..d8dd361
--- /dev/null
+++ b/src/runtime/vdso_linux_s390x.go
@@ -0,0 +1,27 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && s390x
+// +build linux
+// +build s390x
+
+package runtime
+
+const (
+ // vdsoArrayMax is the byte-size of a maximally sized array on this architecture.
+ // See cmd/compile/internal/s390x/galign.go arch.MAXWIDTH initialization.
+ vdsoArrayMax = 1<<50 - 1
+)
+
+var vdsoLinuxVersion = vdsoVersionKey{"LINUX_2.6.29", 0x75fcbb9}
+
+var vdsoSymbolKeys = []vdsoSymbolKey{
+ {"__kernel_clock_gettime", 0xb0cd725, 0xdfa941fd, &vdsoClockgettimeSym},
+}
+
+// initialize with vsyscall fallbacks
+var (
+ vdsoClockgettimeSym uintptr = 0
+ vdsoGettimeofdaySym uintptr = 0
+)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
1 comment:
Patchset:
Thanks. This will be for 1.19.
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
1 comment:
Patchset:
Will this potentially be susceptible to the same issue exhibited in https://github.com/golang/go/pull/46767?
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Axel Busch, Keith Randall.
1 comment:
Patchset:
As far as I understand the bug is concerning about the register with g content. […]
I think this change would make s390x susceptible to the issue Derek saw on ppc64 (thanks for the detailed comments Derek!). The vDSO code is free to temporarily change R13 so long as it restores it to its original value before returning. This probably isn't a problem when compiling with cgo support since g will be restored from TLS when an interrupt occurs but might well cause issues when compiling without cgo support and these issues could be hidden because the code in question doesn't trample R13 right now.
You may want to consider calling STCKE to get the time directly instead. I believe it provides all the functionality needed without having to deal with vDSO or system calls at all.
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
1 comment:
Patchset:
Will this potentially be susceptible to the same issue exhibited in https://github. […]
As far as I understand the bug is concerning about the register with g content. As far as I know g is stored in R13 (s390x). According to ELF ABI for s390x (https://github.com/IBM/s390x-abi) R13 is a call-saved register and preserves r6-r13. So if one of these registers are needed GCC will arrange its previous content to be saved during function prologue and will restore it before exiting. This also works when a signal is triggered during a function. Here, of course the content of those registers could be modified. Nevertheless unwinding works. The Dwarf call frame is aware about where the previous content of the registers was stored on the stack. The unwinder can then restore the values of the registers. From an ELF ABI perspective it should be fine. However, not sure if golang does something different here and has other requirements.
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
1 comment:
Patchset:
I think this change would make s390x susceptible to the issue Derek saw on ppc64 (thanks for the det […]
Thank you Mike for your helpful comments. I am working on a change to avoid that issue.
Derek, did you write a test for this when you fixed the power issue? So maybe like a function that tramples R13/R30 combined with a signal trap?
Another question to understand this better would be why the problem only seems to occur on power, arm and now also s390x. I don't see any code for this on amd64. But even if the corresponding register with g is not modified in the kernel there, one cannot guarantee that this cannot change in a coming kernel change.
Regarding the TOD clock: I think we should go further with the ABI translation in order to prevent coming changes in the kernel require changes in golang as well to avoid async timers. From the point of view of maintainability, this seems to me to be more appropriate. Nevertheless, good idea, thanks for the thought.
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
Gerrit Bot uploaded patch set #2 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: 2764f60002cdfb8f4b85f084c2c21bece59bec32
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/vdso_elf64.go
A src/runtime/vdso_linux_s390x.go
M src/runtime/sys_linux_s390x.s
M src/runtime/signal_unix.go
M src/runtime/vdso_linux.go
M src/runtime/os_linux_novdso.go
M src/runtime/vdso_in_none.go
7 files changed, 222 insertions(+), 27 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
1 comment:
Patchset:
Thank you Mike for your helpful comments. I am working on a change to avoid that issue. […]
Done
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Keith Randall.
Gerrit Dou uploaded patch set #3 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: 3fe041bb999599d1dd3c8fa0b0b4f1e4f9acda84
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/vdso_elf64.go
A src/runtime/vdso_linux_s390x.go
M src/runtime/sys_linux_s390x.s
M src/runtime/signal_unix.go
M src/runtime/vdso_linux.go
M src/runtime/os_linux_novdso.go
M src/runtime/vdso_in_none.go
7 files changed, 227 insertions(+), 30 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
1 comment:
Patchset:
Thanks. This will be for 1.19.
Hey together :) Are we still on track for the 1.19 release or do I need to do anything else to have the patch included in the next release?
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
Gerrit Bot uploaded patch set #4 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: cde61deab79d06d178bc75a0d76d91f37d3986dd
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/os_linux_novdso.go
M src/runtime/signal_unix.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_elf64.go
M src/runtime/vdso_in_none.go
M src/runtime/vdso_linux.go
A src/runtime/vdso_linux_s390x.go
7 files changed, 227 insertions(+), 30 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
Patch set 4:Code-Review +1
2 comments:
Patchset:
I don't have enough background to review this thoroughly but I think it looks good based on comparing it to the other archs. Just one comment on an unused variable.
File src/runtime/vdso_linux_s390x.go:
Patch Set #4, Line 26: vdsoGettimeofdaySym uintptr = 0
I don't think this variable is needed
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
Gerrit Bot uploaded patch set #5 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: 9b3d18e6f90c35638a9678ef0b80cfe4621c133b
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/os_linux_novdso.go
M src/runtime/signal_unix.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_elf64.go
M src/runtime/vdso_in_none.go
M src/runtime/vdso_linux.go
A src/runtime/vdso_linux_s390x.go
7 files changed, 226 insertions(+), 30 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Jonathan Albrecht, Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
1 comment:
File src/runtime/vdso_linux_s390x.go:
Patch Set #4, Line 26: vdsoGettimeofdaySym uintptr = 0
I don't think this variable is needed
Thanks Jonathan, you are right. Just removed the var
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Jonathan Albrecht, Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
1 comment:
File src/runtime/vdso_linux_s390x.go:
Patch Set #4, Line 26: vdsoGettimeofdaySym uintptr = 0
Thanks Jonathan, you are right. […]
Done
Attention is currently required from: Jonathan Albrecht, Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
Patch set 5:Run-TryBot +1
1 comment:
Patchset:
TRY=s390x
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Jonathan Albrecht, Michael Munday, Derek Parker, Michael Knyszek, Austin Clements, Michael Pratt, Ian Lance Taylor, Keith Randall.
2 comments:
Patchset:
The go native bits look OK, however I still need to read up on the various calling conventions to make sure I understand the ASM.
File src/runtime/sys_linux_s390x.s:
Minor nit and request, usually the ASM opcode is preceded by a tab, and if there are arguments, they are separated from the opcode with a tab.
Similarly, comments are usually aligned to same column (with spaces) in a sequence of instructions without an extra newline separating them.
This makes it a little easier to follow.
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
1 comment:
Patchset:
The go native bits look OK, however I still need to read up on the various calling conventions to ma […]
Hi Paul, thanks! Did you already have time to have an insight in the ASM code?
Fixing the tabs is no problem, I can change that
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
1 comment:
Patchset:
Axel, please add Bill O-Farrell as a reviewer. He knows more about s390x.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Michael Knyszek, Michael Munday, Michael Pratt.
4 comments:
File src/runtime/sys_linux_s390x.s:
Patch Set #5, Line 228: 16(R15)
This might be more clear if written relative to SP (likewise in other stack pointer relative ops). (I think that is "-16(SP)"?). I am guessing this is for SIGPROF traceback support? Adding a small comment here like "Stash VDSO SP/PC to stack to support SIGPROF traceback. Restore on exit." is probably helpful.
Does Z have a link register? Is this more like "return address register" (from my reading of the ABI).
Does Z need to account for the fixed frame size here?
Can you clarify this comment? This is the pointer to the timespec struct, right?
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt.
1 comment:
Patchset:
Axel, please add Bill O-Farrell as a reviewer. He knows more about s390x.
Tried, but can not do this. I think I do not have the authority.Could you try? You are reviewer at least :)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
Patch set 5:Code-Review +1
6 comments:
Patchset:
Hi Paul, thanks! Did you already have time to have an insight in the ASM code? […]
Done
File src/runtime/sys_linux_s390x.s:
Minor nit and request, usually the ASM opcode is preceded by a tab, and if there are arguments, they […]
fixed
Patch Set #5, Line 228: 16(R15)
This might be more clear if written relative to SP (likewise in other stack pointer relative ops). […]
Right, we need to store those two registers on the stack to restore them later on. This is, because we run out of saved registers (registers that are restored after BL). Actually addressing with -16(SP) would seem to be the way to go according to the documentation. Unfortunately this does not work. Since R15 is the corresponding register the analogue representation would be 16(R15). This also corresponds to similar code already included in the runtime.
Does Z have a link register? Is this more like "return address register" (from my reading of the ABI […]
Agreed! The comment is wrong. I'll fix that.
Does Z need to account for the fixed frame size here?
In the other s390x asm code there is no fixed frame contained. At least we can find another ret+0. But maybe this would be a question that could answered by Bill
Can you clarify this comment? This is the pointer to the timespec struct, right?
Right, R3 identifies what function is called (e.g. nanotime or walltime), while R4 contains the results. This is why R15 is written to R3 and $ret+0 and $sec+0 respectively have been written to R4.
See https://man7.org/linux/man-pages/man3/clock_gettime.3.html
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
Axel Busch removed a vote from this change.
Attention is currently required from: Austin Clements, Bill O'Farrell, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
Gerrit Bot uploaded patch set #6 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: a425aa4a2549dd8515a3d0309fba315665a21f41
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/os_linux_novdso.go
M src/runtime/signal_unix.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_elf64.go
M src/runtime/vdso_in_none.go
M src/runtime/vdso_linux.go
A src/runtime/vdso_linux_s390x.go
7 files changed, 223 insertions(+), 27 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Bill O'Farrell, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
Gerrit Bot uploaded patch set #7 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: 951ea5d7436d5dac5d38cc5e27312a675db5183d
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/os_linux_novdso.go
M src/runtime/signal_unix.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_elf64.go
M src/runtime/vdso_in_none.go
M src/runtime/vdso_linux.go
A src/runtime/vdso_linux_s390x.go
7 files changed, 222 insertions(+), 26 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Axel Busch, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt, Paul Murphy.
Patch set 7:Code-Review +1
2 comments:
Patchset:
This all looks good.
File src/runtime/sys_linux_s390x.s:
In the other s390x asm code there is no fixed frame contained. At least we can find another ret+0. […]
If I understand the question, this is not a concern for Linux on s390x.
Attention is currently required from: Austin Clements, Axel Busch, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt.
Patch set 7:Code-Review +2
2 comments:
Patchset:
Axel, once you've resolved some minor formatting issues, this looks ready to submit. Be sure to resolve the outstanding comments in all patchsets. Then, this should appear on the dashboard for google to complete the Review-Enforcement requirement.
Thank you for your contribution.
File src/runtime/sys_linux_s390x.s:
Trivial nit, the spacing between opcode and operands uses hard tabs in this file. We should match the existing format.
Similarly, aligning the comments to the same column helps readability. There are a few misalignments here.
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Axel Busch, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt.
Gerrit Bot uploaded patch set #8 to this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: 8f6e918a45cf8c5aadc5c203949a8ce4e372086f
GitHub-Pull-Request: golang/go#49717
---
M src/runtime/os_linux_novdso.go
M src/runtime/signal_unix.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_elf64.go
M src/runtime/vdso_in_none.go
M src/runtime/vdso_linux.go
A src/runtime/vdso_linux_s390x.go
7 files changed, 216 insertions(+), 22 deletions(-)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt.
1 comment:
File src/runtime/sys_linux_s390x.s:
Trivial nit, the spacing between opcode and operands uses hard tabs in this file. […]
Okay, I fixed the formatting issues. I hope this is fine now :) Unfortunately for tabs regarding code comments this is just as inconsistent in other code parts as well. Again, I hope this is fine now
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt.
Patch set 8:Run-TryBot +1Code-Review +2
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Knyszek, Michael Munday, Michael Pratt.
Patch set 8:Code-Review +1
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Munday, Michael Pratt.
Attention is currently required from: Austin Clements, Derek Parker, Ian Lance Taylor, Jonathan Albrecht, Keith Randall, Lynn Boger, Michael Munday, Michael Pratt.
Patch set 8:Code-Review +1
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.
Paul Murphy submitted this change.
runtime: enable vDSO support for s390x architecture
This change adds support for vDSO for s390x architecture. This avoids the use of system calls in nanotime and walltime and accelerates them by factor 4-5.
Benchmarks:
100,000,000 x time.Now():
syscall fallback 13923ms 139.23 ns/op
vDSO enabled 2640ms 26.40 ns/op
Change-Id: Ic679fe31048379e59ccf83b400140f13c9d49696
GitHub-Last-Rev: 8f6e918a45cf8c5aadc5c203949a8ce4e372086f
GitHub-Pull-Request: golang/go#49717
Reviewed-on: https://go-review.googlesource.com/c/go/+/365995
Run-TryBot: Paul Murphy <mu...@ibm.com>
TryBot-Result: Gopher Robot <go...@golang.org>
Reviewed-by: David Chase <drc...@google.com>
Reviewed-by: Paul Murphy <mu...@ibm.com>
Reviewed-by: Michael Knyszek <mkny...@google.com>
Reviewed-by: Jonathan Albrecht <jonathan...@ibm.com>
Reviewed-by: Heschi Kreinick <hes...@google.com>
Reviewed-by: Bill O'Farrell <billo...@gmail.com>
---
M src/runtime/os_linux_novdso.go
M src/runtime/signal_unix.go
M src/runtime/sys_linux_s390x.s
M src/runtime/vdso_elf64.go
M src/runtime/vdso_in_none.go
M src/runtime/vdso_linux.go
A src/runtime/vdso_linux_s390x.go
7 files changed, 225 insertions(+), 22 deletions(-)
diff --git a/src/runtime/os_linux_novdso.go b/src/runtime/os_linux_novdso.go
index b06716d..1882b90 100644
--- a/src/runtime/os_linux_novdso.go
+++ b/src/runtime/os_linux_novdso.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64
+//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x
package runtime
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 66a5c94..69a4103 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -397,7 +397,7 @@
//go:nosplit
func sigFetchG(c *sigctxt) *g {
switch GOARCH {
- case "arm", "arm64", "ppc64", "ppc64le", "riscv64":
+ case "arm", "arm64", "ppc64", "ppc64le", "riscv64", "s390x":
if !iscgo && inVDSOPage(c.sigpc()) {
// When using cgo, we save the g on TLS and load it from there
// in sigtramp. Just use that.
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index 91ce1b3..c82cb9b 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -215,30 +215,178 @@
RET
// func walltime() (sec int64, nsec int32)
-TEXT runtime·walltime(SB),NOSPLIT,$16
- MOVW $0, R2 // CLOCK_REALTIME
+TEXT runtime·walltime(SB),NOSPLIT,$32-12
+ MOVW $0, R2 // CLOCK_REALTIME
+ MOVD R15, R7 // Backup stack pointer
+
+ MOVD g_m(g), R6 //m
+
+ MOVD runtime·vdsoClockgettimeSym(SB), R9 // Check for VDSO availability
+ CMPBEQ R9, $0, fallback
+
+ MOVD m_vdsoPC(R6), R4
+ MOVD R4, 16(R15)
+ MOVD m_vdsoSP(R6), R4
+ MOVD R4, 24(R15)
+
+ MOVD R14, R8 // Backup return address
+ MOVD $sec+0(FP), R4 // return parameter caller
+
+ MOVD R8, m_vdsoPC(R6)
+ MOVD R4, m_vdsoSP(R6)
+
+ MOVD m_curg(R6), R5
+ CMP g, R5
+ BNE noswitch
+
+ MOVD m_g0(R6), R4
+ MOVD (g_sched+gobuf_sp)(R4), R15 // Set SP to g0 stack
+
+noswitch:
+ SUB $16, R15 // reserve 2x 8 bytes for parameters
+ MOVD $~7, R4 // align to 8 bytes because of gcc ABI
+ AND R4, R15
+ MOVD R15, R3 // R15 needs to be in R3 as expected by kernel_clock_gettime
+
+ MOVB runtime·iscgo(SB),R12
+ CMPBNE R12, $0, nosaveg
+
+ MOVD m_gsignal(R6), R12 // g.m.gsignal
+ CMPBEQ R12, $0, nosaveg
+
+ CMPBEQ g, R12, nosaveg
+ MOVD (g_stack+stack_lo)(R12), R12 // g.m.gsignal.stack.lo
+ MOVD g, (R12)
+
+ BL R9 // to vdso lookup
+
+ MOVD $0, (R12)
+
+ JMP finish
+
+nosaveg:
+ BL R9 // to vdso lookup
+
+finish:
+ MOVD 0(R15), R3 // sec
+ MOVD 8(R15), R5 // nsec
+ MOVD R7, R15 // Restore SP
+
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVD 24(R15), R12
+ MOVD R12, m_vdsoSP(R6)
+ MOVD 16(R15), R12
+ MOVD R12, m_vdsoPC(R6)
+
+return:
+ // sec is in R3, nsec in R5
+ // return nsec in R3
+ MOVD R3, sec+0(FP)
+ MOVW R5, nsec+8(FP)
+ RET
+
+ // Syscall fallback
+fallback:
MOVD $tp-16(SP), R3
MOVW $SYS_clock_gettime, R1
SYSCALL
- LMG tp-16(SP), R2, R3
+ LMG tp-16(SP), R2, R3
// sec is in R2, nsec in R3
MOVD R2, sec+0(FP)
MOVW R3, nsec+8(FP)
RET
-TEXT runtime·nanotime1(SB),NOSPLIT,$16
- MOVW $1, R2 // CLOCK_MONOTONIC
- MOVD $tp-16(SP), R3
- MOVW $SYS_clock_gettime, R1
- SYSCALL
- LMG tp-16(SP), R2, R3
- // sec is in R2, nsec in R3
- // return nsec in R2
- MULLD $1000000000, R2
- ADD R3, R2
- MOVD R2, ret+0(FP)
+TEXT runtime·nanotime1(SB),NOSPLIT,$32-8
+ MOVW $1, R2 // CLOCK_MONOTONIC
+
+ MOVD R15, R7 // Backup stack pointer
+
+ MOVD g_m(g), R6 //m
+
+ MOVD runtime·vdsoClockgettimeSym(SB), R9 // Check for VDSO availability
+ CMPBEQ R9, $0, fallback
+
+ MOVD m_vdsoPC(R6), R4
+ MOVD R4, 16(R15)
+ MOVD m_vdsoSP(R6), R4
+ MOVD R4, 24(R15)
+
+ MOVD R14, R8 // Backup return address
+ MOVD $ret+0(FP), R4 // caller's SP
+
+ MOVD R8, m_vdsoPC(R6)
+ MOVD R4, m_vdsoSP(R6)
+
+ MOVD m_curg(R6), R5
+ CMP g, R5
+ BNE noswitch
+
+ MOVD m_g0(R6), R4
+ MOVD (g_sched+gobuf_sp)(R4), R15 // Set SP to g0 stack
+
+noswitch:
+ SUB $16, R15 // reserve 2x 8 bytes for parameters
+ MOVD $~7, R4 // align to 8 bytes because of gcc ABI
+ AND R4, R15
+ MOVD R15, R3 // R15 needs to be in R3 as expected by kernel_clock_gettime
+
+ MOVB runtime·iscgo(SB),R12
+ CMPBNE R12, $0, nosaveg
+
+ MOVD m_gsignal(R6), R12 // g.m.gsignal
+ CMPBEQ R12, $0, nosaveg
+
+ CMPBEQ g, R12, nosaveg
+ MOVD (g_stack+stack_lo)(R12), R12 // g.m.gsignal.stack.lo
+ MOVD g, (R12)
+
+ BL R9 // to vdso lookup
+
+ MOVD $0, (R12)
+
+ JMP finish
+
+nosaveg:
+ BL R9 // to vdso lookup
+
+finish:
+ MOVD 0(R15), R3 // sec
+ MOVD 8(R15), R5 // nsec
+ MOVD R7, R15 // Restore SP
+
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+
+ MOVD 24(R15), R12
+ MOVD R12, m_vdsoSP(R6)
+ MOVD 16(R15), R12
+ MOVD R12, m_vdsoPC(R6)
+
+return:
+ // sec is in R3, nsec in R5
+ // return nsec in R3
+ MULLD $1000000000, R3
+ ADD R5, R3
+ MOVD R3, ret+0(FP)
RET
+ // Syscall fallback
+fallback:
+ MOVD $tp-16(SP), R3
+ MOVD $SYS_clock_gettime, R1
+ SYSCALL
+ LMG tp-16(SP), R2, R3
+ MOVD R3, R5
+ MOVD R2, R3
+ JMP return
+
TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
MOVW how+0(FP), R2
MOVD new+8(FP), R3
diff --git a/src/runtime/vdso_elf64.go b/src/runtime/vdso_elf64.go
index d46d6f8..b50e58f 100644
--- a/src/runtime/vdso_elf64.go
+++ b/src/runtime/vdso_elf64.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && (amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64)
+//go:build linux && (amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x)
package runtime
diff --git a/src/runtime/vdso_in_none.go b/src/runtime/vdso_in_none.go
index 618bd39..a11ecb0 100644
--- a/src/runtime/vdso_in_none.go
+++ b/src/runtime/vdso_in_none.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64) || !linux
+//go:build (linux && !386 && !amd64 && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x) || !linux
package runtime
diff --git a/src/runtime/vdso_linux.go b/src/runtime/vdso_linux.go
index 2ebdd44..36b9f42 100644
--- a/src/runtime/vdso_linux.go
+++ b/src/runtime/vdso_linux.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && (386 || amd64 || arm || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64)
+//go:build linux && (386 || amd64 || arm || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x)
package runtime
@@ -232,9 +232,11 @@
if !info.isGNUHash {
// Old-style DT_HASH table.
for _, k := range vdsoSymbolKeys {
- for chain := info.bucket[k.symHash%uint32(len(info.bucket))]; chain != 0; chain = info.chain[chain] {
- if apply(chain, k) {
- break
+ if len(info.bucket) > 0 {
+ for chain := info.bucket[k.symHash%uint32(len(info.bucket))]; chain != 0; chain = info.chain[chain] {
+ if apply(chain, k) {
+ break
+ }
}
}
}
diff --git a/src/runtime/vdso_linux_s390x.go b/src/runtime/vdso_linux_s390x.go
new file mode 100644
index 0000000..85f78bb
--- /dev/null
+++ b/src/runtime/vdso_linux_s390x.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && s390x
+// +build linux
+// +build s390x
+
+package runtime
+
+const (
+ // vdsoArrayMax is the byte-size of a maximally sized array on this architecture.
+ // See cmd/compile/internal/s390x/galign.go arch.MAXWIDTH initialization.
+ vdsoArrayMax = 1<<50 - 1
+)
+
+var vdsoLinuxVersion = vdsoVersionKey{"LINUX_2.6.29", 0x75fcbb9}
+
+var vdsoSymbolKeys = []vdsoSymbolKey{
+ {"__kernel_clock_gettime", 0xb0cd725, 0xdfa941fd, &vdsoClockgettimeSym},
+}
+
+// initialize with vsyscall fallbacks
+var (
+ vdsoClockgettimeSym uintptr = 0
+)
To view, visit change 365995. To unsubscribe, or for help writing mail filters, visit settings.