Re: [PATCH v4.16-rc5 1/2] x86/vdso: VDSO should handle clock_gettime(CLOCK_MONOTONIC_RAW) without syscall
Hi, Thank you for the patch! Yet something to improve: [auto build test ERROR on v4.16-rc4] [also build test ERROR on next-20180319] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/jason-vas-dias-gmail-com/x86-vdso-VDSO-should-handle-clock_gettime-CLOCK_MONOTONIC_RAW-without-syscall/20180319-021527 config: x86_64-randconfig-in0-03200329 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 Note: the linux-review/jason-vas-dias-gmail-com/x86-vdso-VDSO-should-handle-clock_gettime-CLOCK_MONOTONIC_RAW-without-syscall/20180319-021527 HEAD e19190a6cf1c0e065fe6e3b1b3073e1586d0b6a9 builds fine. It only hurts bisectibility. All errors (new ones prefixed by >>): >> arch/x86/entry/vdso/vdso32.so.dbg: undefined symbols found --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v4.16-rc5 1/2] x86/vdso: VDSO should handle clock_gettime(CLOCK_MONOTONIC_RAW) without syscall
Hi, Thank you for the patch! Yet something to improve: [auto build test ERROR on v4.16-rc4] [also build test ERROR on next-20180316] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/jason-vas-dias-gmail-com/x86-vdso-VDSO-should-handle-clock_gettime-CLOCK_MONOTONIC_RAW-without-syscall/20180319-021527 config: x86_64-randconfig-v0-03200333 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 Note: the linux-review/jason-vas-dias-gmail-com/x86-vdso-VDSO-should-handle-clock_gettime-CLOCK_MONOTONIC_RAW-without-syscall/20180319-021527 HEAD e19190a6cf1c0e065fe6e3b1b3073e1586d0b6a9 builds fine. It only hurts bisectibility. All errors (new ones prefixed by >>): arch/x86/entry/vdso/vclock_gettime.o: In function `__vdso_clock_gettime': >> arch/x86/entry/vdso/vclock_gettime.c:314: undefined reference to >> `__x86_indirect_thunk_rax' /usr/bin/ld: arch/x86/entry/vdso/vclock_gettime.o: relocation R_X86_64_PC32 against undefined symbol `__x86_indirect_thunk_rax' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value >> collect2: error: ld returned 1 exit status -- >> objcopy: 'arch/x86/entry/vdso/vdso64.so.dbg': No such file -- arch/x86//entry/vdso/vclock_gettime.o: In function `__vdso_clock_gettime': arch/x86//entry/vdso/vclock_gettime.c:314: undefined reference to `__x86_indirect_thunk_rax' /usr/bin/ld: arch/x86//entry/vdso/vclock_gettime.o: relocation R_X86_64_PC32 against undefined symbol `__x86_indirect_thunk_rax' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value >> collect2: error: ld returned 1 exit status vim +314 arch/x86/entry/vdso/vclock_gettime.c da15cfda arch/x86/vdso/vclock_gettime.c John Stultz 2009-08-19 311 23adec55 arch/x86/vdso/vclock_gettime.c Steven Rostedt 2008-05-12 312 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) 2aae950b arch/x86_64/vdso/vclock_gettime.cAndi Kleen 2007-07-21 313 { 2aae950b arch/x86_64/vdso/vclock_gettime.cAndi Kleen 2007-07-21 @314 switch (clock) { 2aae950b arch/x86_64/vdso/vclock_gettime.cAndi Kleen 2007-07-21 315 case CLOCK_REALTIME: ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 316 if (do_realtime(ts) == VCLOCK_NONE) ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 317 goto fallback; da15cfda arch/x86/vdso/vclock_gettime.c John Stultz 2009-08-19 318 break; 2aae950b arch/x86_64/vdso/vclock_gettime.cAndi Kleen 2007-07-21 319 case CLOCK_MONOTONIC: ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 320 if (do_monotonic(ts) == VCLOCK_NONE) ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 321 goto fallback; da15cfda arch/x86/vdso/vclock_gettime.c John Stultz 2009-08-19 322 break; d3dd2426 arch/x86/entry/vdso/vclock_gettime.c jason.vas.d...@gmail.com 2018-03-17 323 case CLOCK_MONOTONIC_RAW: d3dd2426 arch/x86/entry/vdso/vclock_gettime.c jason.vas.d...@gmail.com 2018-03-17 324 if (do_monotonic_raw(ts) == VCLOCK_NONE) d3dd2426 arch/x86/entry/vdso/vclock_gettime.c jason.vas.d...@gmail.com 2018-03-17 325 goto fallback; d3dd2426 arch/x86/entry/vdso/vclock_gettime.c jason.vas.d...@gmail.com 2018-03-17 326 break; da15cfda arch/x86/vdso/vclock_gettime.c John Stultz 2009-08-19 327 case CLOCK_REALTIME_COARSE: ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 328 do_realtime_coarse(ts); ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 329 break; da15cfda arch/x86/vdso/vclock_gettime.c John Stultz 2009-08-19 330 case CLOCK_MONOTONIC_COARSE: ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 331 do_monotonic_coarse(ts); ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 332 break; ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 333 default: ce39c640 arch/x86/vdso/vclock_gettime.c Stefani Seibold 2014-03-17 334 goto fallback; 2aae950b arch/x86_64/vdso/vclock_gettime.cAndi Kleen 2007-07-21 335 } 0d7b8547 arch/x86/vdso/vclock_gettime.c Andy
[PATCH v4.16-rc5 1/2] x86/vdso: VDSO should handle clock_gettime(CLOCK_MONOTONIC_RAW) without syscall
This patch makes the vDSO handle clock_gettime(CLOCK_MONOTONIC_RAW,&ts) calls in the same way it handles clock_gettime(CLOCK_MONOTONIC,&ts) calls, reducing latency from @ 200-1000ns to @ 20ns. diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index f19856d..843b0a6 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -182,27 +182,49 @@ notrace static u64 vread_tsc(void) return last; } -notrace static inline u64 vgetsns(int *mode) +notrace static inline __always_inline u64 vgetcycles(int *mode) { - u64 v; - cycles_t cycles; - - if (gtod->vclock_mode == VCLOCK_TSC) - cycles = vread_tsc(); + switch (gtod->vclock_mode) { + case VCLOCK_TSC: + return vread_tsc(); #ifdef CONFIG_PARAVIRT_CLOCK - else if (gtod->vclock_mode == VCLOCK_PVCLOCK) - cycles = vread_pvclock(mode); + case VCLOCK_PVCLOCK: + return vread_pvclock(mode); #endif #ifdef CONFIG_HYPERV_TSCPAGE - else if (gtod->vclock_mode == VCLOCK_HVCLOCK) - cycles = vread_hvclock(mode); + case VCLOCK_HVCLOCK: + return vread_hvclock(mode); #endif - else + default: + break; + } + return 0; +} + +notrace static inline u64 vgetsns(int *mode) +{ + u64 v; + cycles_t cycles = vgetcycles(mode); + + if (cycles == 0) return 0; + v = (cycles - gtod->cycle_last) & gtod->mask; return v * gtod->mult; } +notrace static inline u64 vgetsns_raw(int *mode) +{ + u64 v; + cycles_t cycles = vgetcycles(mode); + + if (cycles == 0) + return 0; + + v = (cycles - gtod->cycle_last) & gtod->mask; + return v * gtod->raw_mult; +} + /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ notrace static int __always_inline do_realtime(struct timespec *ts) { @@ -246,6 +268,27 @@ notrace static int __always_inline do_monotonic(struct timespec *ts) return mode; } +notrace static __always_inline int do_monotonic_raw(struct timespec *ts) +{ + unsigned long seq; + u64 ns; + int mode; + + do { + seq = gtod_read_begin(gtod); + mode = gtod->vclock_mode; + ts->tv_sec = gtod->monotonic_time_raw_sec; + ns = gtod->monotonic_time_raw_nsec; + ns += vgetsns_raw(&mode); + ns >>= gtod->raw_shift; + } while (unlikely(gtod_read_retry(gtod, seq))); + + ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); + ts->tv_nsec = ns; + + return mode; +} + notrace static void do_realtime_coarse(struct timespec *ts) { unsigned long seq; @@ -277,6 +320,10 @@ notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) if (do_monotonic(ts) == VCLOCK_NONE) goto fallback; break; + case CLOCK_MONOTONIC_RAW: + if (do_monotonic_raw(ts) == VCLOCK_NONE) + goto fallback; + break; case CLOCK_REALTIME_COARSE: do_realtime_coarse(ts); break; diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c b/arch/x86/entry/vsyscall/vsyscall_gtod.c index e1216dd..c4d89b6 100644 --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c @@ -44,6 +44,8 @@ void update_vsyscall(struct timekeeper *tk) vdata->mask = tk->tkr_mono.mask; vdata->mult = tk->tkr_mono.mult; vdata->shift= tk->tkr_mono.shift; + vdata->raw_mult = tk->tkr_raw.mult; + vdata->raw_shift= tk->tkr_raw.shift; vdata->wall_time_sec= tk->xtime_sec; vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; @@ -74,5 +76,8 @@ void update_vsyscall(struct timekeeper *tk) vdata->monotonic_time_coarse_sec++; } + vdata->monotonic_time_raw_sec = tk->raw_sec; + vdata->monotonic_time_raw_nsec = tk->tkr_raw.xtime_nsec; + gtod_write_end(vdata); } diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index fb856c9..ec1a37c 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h @@ -22,7 +22,8 @@ struct vsyscall_gtod_data { u64 mask; u32 mult; u32 shift; - + u32 raw_mult; + u32 raw_shift; /* open coded 'struct timespec' */ u64 wall_time_snsec; gtod_long_t wall_time_sec; @@ -32,6 +33,8 @@ struct vsyscall_gtod_data { gtod_long_t wall_time_coarse_nsec; gtod_long_t monotonic_time_coarse_sec; gtod_long_t monotonic_time_coarse_nsec; + gtod_long_t monotonic_time_raw_sec; + gtod_long_t monotonic_time_raw_ns