Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vdso/helpers: Add helpers for seqlocks of single vdso_clock

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.

[ tglx: Move the SMP memory barriers to the call sites and get rid of the
confusing first/last arguments and conditional barriers ]

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-4-df7d9f87b9b8@linutronix.de

authored by

Thomas Weißschuh and committed by
Thomas Gleixner
ad64d71d 76164ca0

+40 -14
+40 -14
include/vdso/helpers.h
··· 28 28 return seq != start; 29 29 } 30 30 31 + static __always_inline void vdso_write_seq_begin(struct vdso_clock *vc) 32 + { 33 + /* 34 + * WRITE_ONCE() is required otherwise the compiler can validly tear 35 + * updates to vc->seq and it is possible that the value seen by the 36 + * reader is inconsistent. 37 + */ 38 + WRITE_ONCE(vc->seq, vc->seq + 1); 39 + } 40 + 41 + static __always_inline void vdso_write_seq_end(struct vdso_clock *vc) 42 + { 43 + /* 44 + * WRITE_ONCE() is required otherwise the compiler can validly tear 45 + * updates to vc->seq and it is possible that the value seen by the 46 + * reader is inconsistent. 47 + */ 48 + WRITE_ONCE(vc->seq, vc->seq + 1); 49 + } 50 + 51 + static __always_inline void vdso_write_begin_clock(struct vdso_clock *vc) 52 + { 53 + vdso_write_seq_begin(vc); 54 + /* Ensure the sequence invalidation is visible before data is modified */ 55 + smp_wmb(); 56 + } 57 + 58 + static __always_inline void vdso_write_end_clock(struct vdso_clock *vc) 59 + { 60 + /* Ensure the data update is visible before the sequence is set valid again */ 61 + smp_wmb(); 62 + vdso_write_seq_end(vc); 63 + } 64 + 31 65 static __always_inline void vdso_write_begin(struct vdso_time_data *vd) 32 66 { 33 67 struct vdso_clock *vc = vd->clock_data; 34 68 35 - /* 36 - * WRITE_ONCE() is required otherwise the compiler can validly tear 37 - * updates to vd[x].seq and it is possible that the value seen by the 38 - * reader is inconsistent. 39 - */ 40 - WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1); 41 - WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1); 69 + vdso_write_seq_begin(&vc[CS_HRES_COARSE]); 70 + vdso_write_seq_begin(&vc[CS_RAW]); 71 + /* Ensure the sequence invalidation is visible before data is modified */ 42 72 smp_wmb(); 43 73 } 44 74 ··· 76 46 { 77 47 struct vdso_clock *vc = vd->clock_data; 78 48 49 + /* Ensure the data update is visible before the sequence is set valid again */ 79 50 smp_wmb(); 80 - /* 81 - * WRITE_ONCE() is required otherwise the compiler can validly tear 82 - * updates to vd[x].seq and it is possible that the value seen by the 83 - * reader is inconsistent. 84 - */ 85 - WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1); 86 - WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1); 51 + vdso_write_seq_end(&vc[CS_HRES_COARSE]); 52 + vdso_write_seq_end(&vc[CS_RAW]); 87 53 } 88 54 89 55 #endif /* !__ASSEMBLY__ */