The commit is pushed to "work" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh8-4.18.0-193.6.3.vz8.4.16 ------> commit b2c945177c8f0933ed37ad7f181a5be71458111a Author: Andrey Ryabinin <aryabi...@virtuozzo.com> Date: Fri Nov 6 17:31:13 2020 +0300
x86_64, vclock_gettime: Use standart division instead of __iter_div_u64_rem() timespec_sub_ns() historically uses __iter_div_u64_rem() for division. Probably it's supposed to be faster /* * Iterative div/mod for use when dividend is not expected to be much * bigger than divisor. */ u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) However in our case ve_start_time may make dividend much bigger than divisor. So let's use standard "/" instead of iterative one. With 0 ve_start_time I wasn't able to see measurable difference, however with big ve_start_time the difference is rather significant: # time ./clock_iter_div real 1m30.224s user 1m30.343s sys 0m0.008s # time taskset ./clock_div real 0m2.757s user 0m1.730s sys 0m0.066s 32-bit vdso doesn't like 64-bit division and doesn't link. I think it needs __udivsi3(). So just fallback to __iter_div_u64_rem() on 32-bit. Fixes: af2c78f571e6 ("ve: add per-ve CLOCK_MONOTONIC time via __vdso_gettimeofday()") https://jira.sw.ru/browse/PSBM-121856 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> --- arch/x86/entry/vdso/vclock_gettime.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index be1de6c4cafa..224dbe80da66 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -229,13 +229,27 @@ notrace static int __always_inline do_realtime(struct timespec *ts) return mode; } +static inline u64 divu64(u64 dividend, u32 divisor, u64 *remainder) +{ + /* 32-bit wants __udivsi3() and fails to link, so fallback to iter */ +#ifndef BUILD_VDSO32 + u64 res; + + res = dividend/divisor; + *remainder = dividend % divisor; + return res; +#else + return __iter_div_u64_rem(dividend, divisor, remainder); +#endif +} + static inline void timespec_sub_ns(struct timespec *ts, u64 ns) { if ((s64)ns <= 0) { - ts->tv_sec += __iter_div_u64_rem(-ns, NSEC_PER_SEC, &ns); + ts->tv_sec += divu64(-ns, NSEC_PER_SEC, &ns); ts->tv_nsec = ns; } else { - ts->tv_sec -= __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); + ts->tv_sec -= divu64(ns, NSEC_PER_SEC, &ns); if (ns) { ts->tv_sec--; ns = NSEC_PER_SEC - ns; _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel