arm64: vdso: replace gettimeofday.S with global vgettimeofday.C
PATCH v5 10/12 arm64: vdso: replace gettimeofday.S with global vgettimeofday.C
Take an effort from the previous 9 patches to recode the arm64 vdso code from assembler to C previously submitted by
Andrew Pinski <[email protected]>, rework it for use in both arm and arm64, overlapping any optimizations for each architecture. But instead of landing it in arm64, land the result into lib/vdso and unify both implementations to simplify future maintenance.
apinski at cavium.com makes the following claims in the original patch:
This allows the compiler to optimize the divide by 1000 and remove the other divides.
On ThunderX, gettimeofday improves by 32%. On ThunderX 2, gettimeofday improves by 18%.
Note I noticed a bug in the old (arm64) implementation of __kernel_clock_getres; it was checking only the lower 32bits of the pointer; this would work for most cases but could fail in a few. (asm fix supplied by Will Deacon <[email protected]> for stable)
<end of claim>
v2:
- turned off profiling, restored quiet_cmd_vdsoas.
v3:
- move arch/arm/vdso/vgettimeofday.c to lib/vdso/vgettimeofday.c.
- adjust vgettimeofday.c to be a better global candidate, switch to using ARCH_PROVIDES_TIMER and __arch_counter_get() as more generic.
v4:
- simplify arch_vdso_read_counter, use read_sysreg.
- Use GENMASK_ULL macro for ARCH_CLOCK_FIXED_MASK.
- update commit message.
- add vdso_wtm_clock_nsec_t, vdso_xtime_clock_sec_t and vdso_raw_time_nsec_t.
v5:
- comment about asm/processor.h and asm/sysreg.h regarding why they have been added in compiler.h for porting clarity.
- add linux/hrtimer.h to compiler.h and comment for porting clarity.
- strip out excess unused definitions in asm-offsets.c.
- fix clang build errors
--- arch/arm64/include/asm/vdso_datapage.h | 23 ++- arch/arm64/kernel/asm-offsets.c | 34 ---- arch/arm64/kernel/vdso.c | 2 +- arch/arm64/kernel/vdso/Makefile | 29 ++- arch/arm64/kernel/vdso/compiler.h | 69 +++++++ arch/arm64/kernel/vdso/datapage.h | 59 ++++++ arch/arm64/kernel/vdso/gettimeofday.S | 328 --------------------------------- arch/arm64/kernel/vdso/vgettimeofday.c | 3 + 8 files changed, 175 insertions(+), 372 deletions(-) create mode 100644 arch/arm64/kernel/vdso/compiler.h create mode 100644 arch/arm64/kernel/vdso/datapage.h delete mode 100644 arch/arm64/kernel/vdso/gettimeofday.S create mode 100644 arch/arm64/kernel/vdso/vgettimeofday.c
arch/arm64/include/asm/vdso_datapage.h +19 -4
@@ -20,16 +20,31 @@ #ifndef __ASSEMBLY__ +#ifndef _VDSO_WTM_CLOCK_SEC_T +#define _VDSO_WTM_CLOCK_SEC_T +typedef __u64 vdso_wtm_clock_nsec_t; +#endif + +#ifndef _VDSO_XTIME_CLOCK_SEC_T +#define _VDSO_XTIME_CLOCK_SEC_T +typedef __u64 vdso_xtime_clock_sec_t; +#endif + +#ifndef _VDSO_RAW_TIME_SEC_T +#define _VDSO_RAW_TIME_SEC_T +typedef __u64 vdso_raw_time_sec_t; +#endif + struct vdso_data { __u64 cs_cycle_last; /* Timebase at clocksource init */ - __u64 raw_time_sec; /* Raw time */ + vdso_raw_time_sec_t raw_time_sec; /* Raw time */ __u64 raw_time_nsec; - __u64 xtime_clock_sec; /* Kernel time */ - __u64 xtime_clock_nsec; + vdso_xtime_clock_sec_t xtime_clock_sec; /* Kernel time */ + __u64 xtime_clock_snsec; __u64 xtime_coarse_sec; /* Coarse time */ __u64 xtime_coarse_nsec; __u64 wtm_clock_sec; /* Wall to monotonic time */ - __u64 wtm_clock_nsec; + vdso_wtm_clock_nsec_t wtm_clock_nsec; __u32 tb_seq_count; /* Timebase sequence counter */ /* cs_* members must be adjacent and in this order (ldp accesses) */ __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */
arch/arm64/kernel/asm-offsets.c +0 -34
@@ -91,40 +91,6 @@ int main(void)DEFINE (DMA_TO_DEVICE ,DMA_TO_DEVICE );DEFINE (DMA_FROM_DEVICE ,DMA_FROM_DEVICE );BLANK (); -DEFINE (CLOCK_REALTIME ,CLOCK_REALTIME ); -DEFINE (CLOCK_MONOTONIC ,CLOCK_MONOTONIC ); -DEFINE (CLOCK_MONOTONIC_RAW ,CLOCK_MONOTONIC_RAW ); -DEFINE (CLOCK_REALTIME_RES ,MONOTONIC_RES_NSEC ); -DEFINE (CLOCK_REALTIME_COARSE ,CLOCK_REALTIME_COARSE ); -DEFINE (CLOCK_MONOTONIC_COARSE ,CLOCK_MONOTONIC_COARSE ); -DEFINE (CLOCK_COARSE_RES ,LOW_RES_NSEC ); -DEFINE (NSEC_PER_SEC ,NSEC_PER_SEC ); -BLANK (); -DEFINE (VDSO_CS_CYCLE_LAST , offsetof(struct vdso_data , cs_cycle_last)); -DEFINE (VDSO_RAW_TIME_SEC , offsetof(struct vdso_data , raw_time_sec)); -DEFINE (VDSO_RAW_TIME_NSEC , offsetof(struct vdso_data , raw_time_nsec)); -DEFINE (VDSO_XTIME_CLK_SEC , offsetof(struct vdso_data , xtime_clock_sec)); -DEFINE (VDSO_XTIME_CLK_NSEC , offsetof(struct vdso_data , xtime_clock_nsec)); -DEFINE (VDSO_XTIME_CRS_SEC , offsetof(struct vdso_data , xtime_coarse_sec)); -DEFINE (VDSO_XTIME_CRS_NSEC , offsetof(struct vdso_data , xtime_coarse_nsec)); -DEFINE (VDSO_WTM_CLK_SEC , offsetof(struct vdso_data , wtm_clock_sec)); -DEFINE (VDSO_WTM_CLK_NSEC , offsetof(struct vdso_data , wtm_clock_nsec)); -DEFINE (VDSO_TB_SEQ_COUNT , offsetof(struct vdso_data , tb_seq_count)); -DEFINE (VDSO_CS_MONO_MULT , offsetof(struct vdso_data , cs_mono_mult)); -DEFINE (VDSO_CS_RAW_MULT , offsetof(struct vdso_data , cs_raw_mult)); -DEFINE (VDSO_CS_SHIFT , offsetof(struct vdso_data , cs_shift)); -DEFINE (VDSO_TZ_MINWEST , offsetof(struct vdso_data , tz_minuteswest)); -DEFINE (VDSO_TZ_DSTTIME , offsetof(struct vdso_data , tz_dsttime)); -DEFINE (VDSO_USE_SYSCALL , offsetof(struct vdso_data , use_syscall)); -BLANK (); -DEFINE (TVAL_TV_SEC , offsetof(struct timeval , tv_sec)); -DEFINE (TVAL_TV_USEC , offsetof(struct timeval , tv_usec)); -DEFINE (TSPEC_TV_SEC , offsetof(struct timespec , tv_sec)); -DEFINE (TSPEC_TV_NSEC , offsetof(struct timespec , tv_nsec)); -BLANK (); -DEFINE (TZ_MINWEST , offsetof(struct timezone , tz_minuteswest)); -DEFINE (TZ_DSTTIME , offsetof(struct timezone , tz_dsttime)); -BLANK ();DEFINE (CPU_BOOT_STACK , offsetof(struct secondary_data , stack));DEFINE (CPU_BOOT_TASK , offsetof(struct secondary_data , task));BLANK ();
arch/arm64/kernel/vdso.c +1 -1
@@ -238,7 +238,7 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->raw_time_sec = tk->raw_sec; vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; + vdso_data->xtime_clock_snsec = tk->tkr_mono.xtime_nsec; vdso_data->cs_mono_mult = tk->tkr_mono.mult; vdso_data->cs_raw_mult = tk->tkr_raw.mult;/* tkr_mono.shift == tkr_raw.shift */
arch/arm64/kernel/vdso/Makefile +24 -5
@@ -6,18 +6,32 @@ # Heavily based on the vDSO Makefiles for other archs. # -obj-vdso := gettimeofday.o note.o sigreturn.o +obj-vdso-s := note.o sigreturn.o +obj-vdso-c := vgettimeofday.o # Build rules -targets := $(obj-vdso) vdso.so vdso.so.dbg -obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) +targets := $(obj-vdso-s) $(obj-vdso-c) vdso.so vdso.so.dbg +obj-vdso-s := $(addprefix $(obj)/, $(obj-vdso-s)) +obj-vdso-c := $(addprefix $(obj)/, $(obj-vdso-c)) +obj-vdso := $(obj-vdso-c) $(obj-vdso-s) -ccflags-y := -shared -fno-common -fno-builtin +ccflags-y := -shared -fno-common -fno-builtin -fno-stack-protector +ccflags-y += -DDISABLE_BRANCH_PROFILING ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) +# Force -O2 to avoid libgcc dependencies +CFLAGS_REMOVE_vgettimeofday.o = -pg -Os +CFLAGS_vgettimeofday.o = -O2 -fPIC +ifneq ($(cc-name),clang) +CFLAGS_vgettimeofday.o += -mcmodel=tiny +endif + # Disable gcov profiling for VDSO code GCOV_PROFILE := n +KASAN_SANITIZE := n +UBSAN_SANITIZE := n +KCOV_INSTRUMENT := n # Workaround for bare-metal (ELF) toolchains that neglect to pass -shared # down to collect2, resulting in silent corruption of the vDSO image.
@@ -50,12 +64,17 @@ include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE $(call if_changed,vdsosym) # Assembly rules for the .S files -$(obj-vdso): %.o: %.S FORCE +$(obj-vdso-s): %.o: %.S FORCE $(call if_changed_dep,vdsoas) +$(obj-vdso-c): %.o: %.c FORCE + $(call if_changed_dep,vdsocc) + # Actual build commands quiet_cmd_vdsold = VDSOL $@ cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@ +quiet_cmd_vdsocc = VDSOC $@ + cmd_vdsocc = ${CC} $(c_flags) -c -o $@ $< quiet_cmd_vdsoas = VDSOA $@ cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
arch/arm64/kernel/vdso/compiler.h new file +69 -0
69 lines not on this page · raw message
arch/arm64/kernel/vdso/datapage.h new file +59 -0
59 lines not on this page · raw message
arch/arm64/kernel/vdso/gettimeofday.S deleted +0 -328
328 lines not on this page · raw message
arch/arm64/kernel/vdso/vgettimeofday.c new file +3 -0
@@ -0,0 +1,3 @@ +#include "compiler.h" +#include "datapage.h" +#include "../../../../lib/vdso/vgettimeofday.c"
Signature · 1 line
2.15.0.403.gc27cc4dac6-goog