Auxiliary clocks will have their vDSO data in a dedicated 'struct vdso_clock', which needs to be synchronized independently.
Add a helper to synchronize a single vDSO clock.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- include/vdso/helpers.h | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h index 0a98fed550ba66a84a620fbbd6aee3e3029b4772..a5679f5efdfdcaaf6efd5f4a317d1f132c3dc617 100644 --- a/include/vdso/helpers.h +++ b/include/vdso/helpers.h @@ -28,32 +28,46 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc, return seq != start; }
-static __always_inline void vdso_write_begin(struct vdso_time_data *vd) +static __always_inline void vdso_write_begin_clock(struct vdso_clock *vc, bool last) { - struct vdso_clock *vc = vd->clock_data; - /* * WRITE_ONCE() is required otherwise the compiler can validly tear - * updates to vd[x].seq and it is possible that the value seen by the + * updates to vc->seq and it is possible that the value seen by the * reader is inconsistent. */ - WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1); - WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1); - smp_wmb(); + WRITE_ONCE(vc->seq, vc->seq + 1); + + if (last) + smp_wmb(); }
-static __always_inline void vdso_write_end(struct vdso_time_data *vd) +static __always_inline void vdso_write_end_clock(struct vdso_clock *vc, bool first) { - struct vdso_clock *vc = vd->clock_data; + if (first) + smp_wmb();
- smp_wmb(); /* * WRITE_ONCE() is required otherwise the compiler can validly tear - * updates to vd[x].seq and it is possible that the value seen by the + * updates to vc->seq and it is possible that the value seen by the * reader is inconsistent. */ - WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1); - WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1); + WRITE_ONCE(vc->seq, vc->seq + 1); +} + +static __always_inline void vdso_write_begin(struct vdso_time_data *vd) +{ + struct vdso_clock *vc = vd->clock_data; + + vdso_write_begin_clock(&vc[CS_HRES_COARSE], false); + vdso_write_begin_clock(&vc[CS_RAW], true); +} + +static __always_inline void vdso_write_end(struct vdso_time_data *vd) +{ + struct vdso_clock *vc = vd->clock_data; + + vdso_write_end_clock(&vc[CS_HRES_COARSE], true); + vdso_write_end_clock(&vc[CS_RAW], false); }
#endif /* !__ASSEMBLY__ */