Commit 4bff8cb5 authored by Sven Schnelle's avatar Sven Schnelle Committed by Vasily Gorbik
Browse files

s390: convert to GENERIC_VDSO



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: default avatarSven Schnelle <svens@linux.ibm.com>
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 98ad45fb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ config S390
	select ARCH_HAS_STRICT_MODULE_RWX
	select ARCH_HAS_SYSCALL_WRAPPER
	select ARCH_HAS_UBSAN_SANITIZE_ALL
	select ARCH_HAS_VDSO_DATA
	select ARCH_HAVE_NMI_SAFE_CMPXCHG
	select ARCH_INLINE_READ_LOCK
	select ARCH_INLINE_READ_LOCK_BH
@@ -118,6 +119,7 @@ config S390
	select GENERIC_CPU_AUTOPROBE
	select GENERIC_CPU_VULNERABILITIES
	select GENERIC_FIND_FIRST_BIT
	select GENERIC_GETTIMEOFDAY
	select GENERIC_SMP_IDLE_THREAD
	select GENERIC_TIME_VSYSCALL
	select HAVE_ALIGNED_STRUCT_PAGE if SLUB
@@ -149,6 +151,7 @@ config S390
	select HAVE_FUNCTION_TRACER
	select HAVE_FUTEX_CMPXCHG if FUTEX
	select HAVE_GCC_PLUGINS
	select HAVE_GENERIC_VDSO
	select HAVE_KERNEL_BZIP2
	select HAVE_KERNEL_GZIP
	select HAVE_KERNEL_LZ4
+7 −0
Original line number Diff line number Diff line
/* 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 */
+2 −23
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#ifndef __S390_VDSO_H__
#define __S390_VDSO_H__

#include <vdso/datapage.h>

/* Default link addresses for the vDSOs */
#define VDSO32_LBASE	0
#define VDSO64_LBASE	0
@@ -18,30 +20,7 @@
 * itself and may change without notice.
 */

struct vdso_data {
	__u64 tb_update_count;		/* Timebase atomicity ctr	0x00 */
	__u64 xtime_tod_stamp;		/* TOD clock for xtime		0x08 */
	__u64 xtime_clock_sec;		/* Kernel time			0x10 */
	__u64 xtime_clock_nsec;		/*				0x18 */
	__u64 xtime_coarse_sec;		/* Coarse kernel time		0x20 */
	__u64 xtime_coarse_nsec;	/*				0x28 */
	__u64 wtom_clock_sec;		/* Wall to monotonic clock	0x30 */
	__u64 wtom_clock_nsec;		/*				0x38 */
	__u64 wtom_coarse_sec;		/* Coarse wall to monotonic	0x40 */
	__u64 wtom_coarse_nsec;		/*				0x48 */
	__u32 tz_minuteswest;		/* Minutes west of Greenwich	0x50 */
	__u32 tz_dsttime;		/* Type of dst correction	0x54 */
	__u32 ectg_available;		/* ECTG instruction present	0x58 */
	__u32 tk_mult;			/* Mult. used for xtime_nsec	0x5c */
	__u32 tk_shift;			/* Shift used for xtime_nsec	0x60 */
	__u32 ts_dir;			/* TOD steering direction	0x64 */
	__u64 ts_end;			/* TOD steering end		0x68 */
	__u32 hrtimer_res;		/* hrtimer resolution		0x70 */
};

struct vdso_per_cpu_data {
	__u64 ectg_timer_base;
	__u64 ectg_user_time;
	/*
	 * Note: node_id and cpu_nr must be at adjacent memory locations.
	 * VDSO userspace must read both values with a single instruction.
+8 −0
Original line number Diff line number Diff line
/* 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 */
+13 −0
Original line number Diff line number Diff line
/* 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 */
Loading