0001
0002 #ifndef __VDSO_HELPERS_H
0003 #define __VDSO_HELPERS_H
0004
0005 #ifndef __ASSEMBLY__
0006
0007 #include <vdso/datapage.h>
0008
0009 static __always_inline u32 vdso_read_begin(const struct vdso_data *vd)
0010 {
0011 u32 seq;
0012
0013 while (unlikely((seq = READ_ONCE(vd->seq)) & 1))
0014 cpu_relax();
0015
0016 smp_rmb();
0017 return seq;
0018 }
0019
0020 static __always_inline u32 vdso_read_retry(const struct vdso_data *vd,
0021 u32 start)
0022 {
0023 u32 seq;
0024
0025 smp_rmb();
0026 seq = READ_ONCE(vd->seq);
0027 return seq != start;
0028 }
0029
0030 static __always_inline void vdso_write_begin(struct vdso_data *vd)
0031 {
0032
0033
0034
0035
0036
0037 WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
0038 WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
0039 smp_wmb();
0040 }
0041
0042 static __always_inline void vdso_write_end(struct vdso_data *vd)
0043 {
0044 smp_wmb();
0045
0046
0047
0048
0049
0050 WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1);
0051 WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1);
0052 }
0053
0054 #endif
0055
0056 #endif