Skip to content

Commit ad64d71

Browse files
t-8chKAGA-KOKO
authored andcommitted
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 <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent 76164ca commit ad64d71

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

include/vdso/helpers.h

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,58 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
2828
return seq != start;
2929
}
3030

31-
static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
31+
static __always_inline void vdso_write_seq_begin(struct vdso_clock *vc)
3232
{
33-
struct vdso_clock *vc = vd->clock_data;
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+
}
3440

41+
static __always_inline void vdso_write_seq_end(struct vdso_clock *vc)
42+
{
3543
/*
3644
* 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
45+
* updates to vc->seq and it is possible that the value seen by the
3846
* reader is inconsistent.
3947
*/
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);
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+
65+
static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
66+
{
67+
struct vdso_clock *vc = vd->clock_data;
68+
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 */
4272
smp_wmb();
4373
}
4474

4575
static __always_inline void vdso_write_end(struct vdso_time_data *vd)
4676
{
4777
struct vdso_clock *vc = vd->clock_data;
4878

79+
/* Ensure the data update is visible before the sequence is set valid again */
4980
smp_wmb();
50-
/*
51-
* WRITE_ONCE() is required otherwise the compiler can validly tear
52-
* updates to vd[x].seq and it is possible that the value seen by the
53-
* reader is inconsistent.
54-
*/
55-
WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
56-
WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
81+
vdso_write_seq_end(&vc[CS_HRES_COARSE]);
82+
vdso_write_seq_end(&vc[CS_RAW]);
5783
}
5884

5985
#endif /* !__ASSEMBLY__ */

0 commit comments

Comments
 (0)