On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
> +static __always_inline
> +bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct 
> __kernel_timespec *ts)
> +{
> +     const struct vdso_clock *vc;
> +     u64 sec, ns;
> +     u32 seq;
> +     u8 idx;
> +
> +     if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
> +             return false;
> +
> +     idx = clock - CLOCK_AUX;
> +     vc = &vd->aux_clock_data[idx];
> +
> +     do {
> +             /*
> +              * Open coded function vdso_read_begin() to handle
> +              * VDSO_CLOCK_TIMENS. See comment in do_hres().
> +              */
> +             while ((seq = READ_ONCE(vc->seq)) & 1) {
> +                     if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == 
> VDSO_CLOCKMODE_TIMENS) {
> +                             vd = __arch_get_vdso_u_timens_data(vd);
> +                             vc = &vd->aux_clock_data[idx];
> +                             break;

This actually wants to be a continue because otherwise @seq contains the
stale value from the initial read of the TIMENS page, which is
0x1. That's a pointless extra round through the below.

With continue it re-reads, but this time the actual value from the time
data page and also takes an eventual odd value into account properly.

I fixed it up locally already.

Thanks,

        tglx

Reply via email to