Message ID | 20240808-sparc-shr64-v2-1-fd18f1b2cea9@protonmail.com |
---|---|
State | New |
Headers | show |
Series | [v2] sparc/vdso: Add helper function for 64-bit right shift on 32-bit target | expand |
Koakuma via B4 Relay <devnull+koachan.protonmail.com@kernel.org> wrote: > From: Koakuma koachan@protonmail.com > > > Add helper function for 64-bit right shift on 32-bit target so that > clang does not emit a runtime library call. > > Signed-off-by: Koakuma koachan@protonmail.com > > --- > Hi~ > > This adds a small function to do 64-bit right shifts for use in vDSO > code, needed so that clang does not emit a call to runtime library. > --- > Changes in v2: > - Move __shr64 to sparc code since there are no other users of it. > - Now that __shr64 is not in portable code, redo it in inline asm for simpler implementation & better performance. > - Link to v1: https://lore.kernel.org/r/20240804-sparc-shr64-v1-1-25050968339a@protonmail.com > --- > arch/sparc/vdso/vclock_gettime.c | 28 ++++++++++++++++++++++++---- > 1 file changed, 24 insertions(+), 4 deletions(-) > > diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c > index e794edde6755..79607804ea1b 100644 > --- a/arch/sparc/vdso/vclock_gettime.c > +++ b/arch/sparc/vdso/vclock_gettime.c > @@ -86,6 +86,11 @@ notrace static long vdso_fallback_gettimeofday(struct __kernel_old_timeval *tv, > } > > #ifdef CONFIG_SPARC64 > +notrace static __always_inline u64 __shr64(u64 val, int amt) > +{ > + return val >> amt; > > +} > + > notrace static __always_inline u64 vread_tick(void) > { > u64 ret; > @@ -102,6 +107,21 @@ notrace static __always_inline u64 vread_tick_stick(void) > return ret; > } > #else > +notrace static __always_inline u64 __shr64(u64 val, int amt) > +{ > + u64 ret; > + > + asm volatile("sllx %H1, 32, %%g1\n\t" > + "srl %L1, 0, %L1\n\t" > + "or %%g1, %L1, %%g1\n\t" > + "srlx %%g1, %2, %L0\n\t" > + "srlx %L0, 32, %H0" > + : "=r" (ret) > + : "r" (val), "r" (amt) > + : "g1"); > + return ret; > +} > + > notrace static __always_inline u64 vread_tick(void) > { > register unsigned long long ret asm("o4"); > @@ -154,7 +174,7 @@ notrace static __always_inline int do_realtime(struct vvar_data *vvar, > ts->tv_sec = vvar->wall_time_sec; > > ns = vvar->wall_time_snsec; > > ns += vgetsns(vvar); > - ns >>= vvar->clock.shift; > > + ns = __shr64(ns, vvar->clock.shift); > > } while (unlikely(vvar_read_retry(vvar, seq))); > > ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); > > @@ -174,7 +194,7 @@ notrace static __always_inline int do_realtime_stick(struct vvar_data *vvar, > ts->tv_sec = vvar->wall_time_sec; > > ns = vvar->wall_time_snsec; > > ns += vgetsns_stick(vvar); > - ns >>= vvar->clock.shift; > > + ns = __shr64(ns, vvar->clock.shift); > > } while (unlikely(vvar_read_retry(vvar, seq))); > > ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); > > @@ -194,7 +214,7 @@ notrace static __always_inline int do_monotonic(struct vvar_data *vvar, > ts->tv_sec = vvar->monotonic_time_sec; > > ns = vvar->monotonic_time_snsec; > > ns += vgetsns(vvar); > - ns >>= vvar->clock.shift; > > + ns = __shr64(ns, vvar->clock.shift); > > } while (unlikely(vvar_read_retry(vvar, seq))); > > ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); > > @@ -214,7 +234,7 @@ notrace static __always_inline int do_monotonic_stick(struct vvar_data *vvar, > ts->tv_sec = vvar->monotonic_time_sec; > > ns = vvar->monotonic_time_snsec; > > ns += vgetsns_stick(vvar); > - ns >>= vvar->clock.shift; > > + ns = __shr64(ns, vvar->clock.shift); > > } while (unlikely(vvar_read_retry(vvar, seq))); > > ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); > > > --- > base-commit: defaf1a2113a22b00dfa1abc0fd2014820eaf065 > change-id: 20240717-sparc-shr64-2f00a7884770 > > Best regards, > -- > Koakuma koachan@protonmail.com > > Hi, is there anything else I need to do for this patch?
diff --git a/arch/sparc/vdso/vclock_gettime.c b/arch/sparc/vdso/vclock_gettime.c index e794edde6755..79607804ea1b 100644 --- a/arch/sparc/vdso/vclock_gettime.c +++ b/arch/sparc/vdso/vclock_gettime.c @@ -86,6 +86,11 @@ notrace static long vdso_fallback_gettimeofday(struct __kernel_old_timeval *tv, } #ifdef CONFIG_SPARC64 +notrace static __always_inline u64 __shr64(u64 val, int amt) +{ + return val >> amt; +} + notrace static __always_inline u64 vread_tick(void) { u64 ret; @@ -102,6 +107,21 @@ notrace static __always_inline u64 vread_tick_stick(void) return ret; } #else +notrace static __always_inline u64 __shr64(u64 val, int amt) +{ + u64 ret; + + __asm__ __volatile__("sllx %H1, 32, %%g1\n\t" + "srl %L1, 0, %L1\n\t" + "or %%g1, %L1, %%g1\n\t" + "srlx %%g1, %2, %L0\n\t" + "srlx %L0, 32, %H0" + : "=r" (ret) + : "r" (val), "r" (amt) + : "g1"); + return ret; +} + notrace static __always_inline u64 vread_tick(void) { register unsigned long long ret asm("o4"); @@ -154,7 +174,7 @@ notrace static __always_inline int do_realtime(struct vvar_data *vvar, ts->tv_sec = vvar->wall_time_sec; ns = vvar->wall_time_snsec; ns += vgetsns(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); @@ -174,7 +194,7 @@ notrace static __always_inline int do_realtime_stick(struct vvar_data *vvar, ts->tv_sec = vvar->wall_time_sec; ns = vvar->wall_time_snsec; ns += vgetsns_stick(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); @@ -194,7 +214,7 @@ notrace static __always_inline int do_monotonic(struct vvar_data *vvar, ts->tv_sec = vvar->monotonic_time_sec; ns = vvar->monotonic_time_snsec; ns += vgetsns(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); @@ -214,7 +234,7 @@ notrace static __always_inline int do_monotonic_stick(struct vvar_data *vvar, ts->tv_sec = vvar->monotonic_time_sec; ns = vvar->monotonic_time_snsec; ns += vgetsns_stick(vvar); - ns >>= vvar->clock.shift; + ns = __shr64(ns, vvar->clock.shift); } while (unlikely(vvar_read_retry(vvar, seq))); ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);