-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert s390 to generic vDSO. There are a few special things on s390: - vDSO can be called without a stack frame - glibc did this in the past. So we need to allocate a stackframe on our own. - The former assembly code used stcke to get the TOD clock and applied time steering to it. We need to do the same in the new code. This is done in the architecture specific __arch_get_hw_counter function. The steering information is stored in an architecure specific area in the vDSO data. - CPUCLOCK_VIRT is now handled with a syscall fallback, which might be slower/less accurate than the old implementation. The getcpu() function stays as an assembly function because there is no generic implementation and the code is just a few lines. Performance number from my system do 100 mio gettimeofday() calls: Plain syscall: 8.6s Generic VDSO: 1.3s old ASM VDSO: 1s So it's a bit slower but still much faster than syscalls. Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
- Loading branch information
Sven Schnelle
authored and
Vasily Gorbik
committed
Aug 26, 2020
1 parent
98ad45f
commit 4bff8cb
Showing
20 changed files
with
221 additions
and
420 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* s390-specific clocksource additions */ | ||
|
||
#ifndef _ASM_S390_CLOCKSOURCE_H | ||
#define _ASM_S390_CLOCKSOURCE_H | ||
|
||
#endif /* _ASM_S390_CLOCKSOURCE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef __ASM_VDSO_CLOCKSOURCE_H | ||
#define __ASM_VDSO_CLOCKSOURCE_H | ||
|
||
#define VDSO_ARCH_CLOCKMODES \ | ||
VDSO_CLOCKMODE_TOD | ||
|
||
#endif /* __ASM_VDSO_CLOCKSOURCE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef __S390_ASM_VDSO_DATA_H | ||
#define __S390_ASM_VDSO_DATA_H | ||
|
||
#include <linux/types.h> | ||
#include <vdso/datapage.h> | ||
|
||
struct arch_vdso_data { | ||
__u64 tod_steering_delta; | ||
__u64 tod_steering_end; | ||
}; | ||
|
||
#endif /* __S390_ASM_VDSO_DATA_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef ASM_VDSO_GETTIMEOFDAY_H | ||
#define ASM_VDSO_GETTIMEOFDAY_H | ||
|
||
#define VDSO_HAS_TIME 1 | ||
|
||
#define VDSO_HAS_CLOCK_GETRES 1 | ||
|
||
#include <asm/timex.h> | ||
#include <asm/unistd.h> | ||
#include <asm/vdso.h> | ||
#include <linux/compiler.h> | ||
|
||
#define vdso_calc_delta __arch_vdso_calc_delta | ||
static __always_inline u64 __arch_vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult) | ||
{ | ||
return (cycles - last) * mult; | ||
} | ||
|
||
static __always_inline const struct vdso_data *__arch_get_vdso_data(void) | ||
{ | ||
return _vdso_data; | ||
} | ||
|
||
static inline u64 __arch_get_hw_counter(s32 clock_mode, const struct vdso_data *vd) | ||
{ | ||
const struct vdso_data *vdso = __arch_get_vdso_data(); | ||
u64 adj, now; | ||
|
||
now = get_tod_clock(); | ||
adj = vdso->arch_data.tod_steering_end - now; | ||
if (unlikely((s64) adj > 0)) | ||
now += (vdso->arch_data.tod_steering_delta < 0) ? (adj >> 15) : -(adj >> 15); | ||
return now; | ||
} | ||
|
||
static __always_inline | ||
long clock_gettime_fallback(clockid_t clkid, struct __kernel_timespec *ts) | ||
{ | ||
register unsigned long r1 __asm__("r1") = __NR_clock_gettime; | ||
register unsigned long r2 __asm__("r2") = (unsigned long)clkid; | ||
register void *r3 __asm__("r3") = ts; | ||
|
||
asm ("svc 0\n" : "+d" (r2) : "d" (r1), "d" (r3) : "cc", "memory"); | ||
return r2; | ||
} | ||
|
||
static __always_inline | ||
long gettimeofday_fallback(register struct __kernel_old_timeval *tv, | ||
register struct timezone *tz) | ||
{ | ||
register unsigned long r1 __asm__("r1") = __NR_gettimeofday; | ||
register unsigned long r2 __asm__("r2") = (unsigned long)tv; | ||
register void *r3 __asm__("r3") = tz; | ||
|
||
asm ("svc 0\n" : "+d" (r2) : "d" (r1), "d" (r3) : "cc", "memory"); | ||
return r2; | ||
} | ||
|
||
static __always_inline | ||
long clock_getres_fallback(clockid_t clkid, struct __kernel_timespec *ts) | ||
{ | ||
register unsigned long r1 __asm__("r1") = __NR_clock_getres; | ||
register unsigned long r2 __asm__("r2") = (unsigned long)clkid; | ||
register void *r3 __asm__("r3") = ts; | ||
|
||
asm ("svc 0\n" : "+d" (r2) : "d" (r1), "d" (r3) : "cc", "memory"); | ||
return r2; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
#ifndef __ASM_VDSO_PROCESSOR_H | ||
#define __ASM_VDSO_PROCESSOR_H | ||
|
||
#define cpu_relax() barrier() | ||
|
||
#endif /* __ASM_VDSO_PROCESSOR_H */ |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef __ASM_VDSO_VSYSCALL_H | ||
#define __ASM_VDSO_VSYSCALL_H | ||
|
||
#ifndef __ASSEMBLY__ | ||
|
||
#include <linux/hrtimer.h> | ||
#include <linux/timekeeper_internal.h> | ||
#include <vdso/datapage.h> | ||
#include <asm/vdso.h> | ||
/* | ||
* Update the vDSO data page to keep in sync with kernel timekeeping. | ||
*/ | ||
|
||
static __always_inline struct vdso_data *__s390_get_k_vdso_data(void) | ||
{ | ||
return vdso_data; | ||
} | ||
#define __arch_get_k_vdso_data __s390_get_k_vdso_data | ||
|
||
/* The asm-generic header needs to be included after the definitions above */ | ||
#include <asm-generic/vdso/vsyscall.h> | ||
|
||
#endif /* !__ASSEMBLY__ */ | ||
|
||
#endif /* __ASM_VDSO_VSYSCALL_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.