diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2019-08-09 13:07:28 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-08-09 13:07:28 -0500 |
commit | 3f61fd41f38328f0a585eaba2d72d339fe9aecda (patch) | |
tree | 4a6fe7dc98a44dec003833a7fa440daa6c304a28 /include/vdso/helpers.h | |
parent | 6ca523d7eb198b78f79df882b7dc4a8c795d8777 (diff) | |
parent | e21a712a9685488f5ce80495b37b9fdbe96c230d (diff) |
Merge tag 'v5.3-rc3' into drm-next-5.4
Linux 5.3-rc3
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'include/vdso/helpers.h')
-rw-r--r-- | include/vdso/helpers.h | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h new file mode 100644 index 000000000000..01641dbb68ef --- /dev/null +++ b/include/vdso/helpers.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __VDSO_HELPERS_H +#define __VDSO_HELPERS_H + +#ifndef __ASSEMBLY__ + +#include <vdso/datapage.h> + +static __always_inline u32 vdso_read_begin(const struct vdso_data *vd) +{ + u32 seq; + + while ((seq = READ_ONCE(vd->seq)) & 1) + cpu_relax(); + + smp_rmb(); + return seq; +} + +static __always_inline u32 vdso_read_retry(const struct vdso_data *vd, + u32 start) +{ + u32 seq; + + smp_rmb(); + seq = READ_ONCE(vd->seq); + return seq != start; +} + +static __always_inline void vdso_write_begin(struct vdso_data *vd) +{ + /* + * WRITE_ONCE it is required otherwise the compiler can validly tear + * updates to vd[x].seq and it is possible that the value seen by the + * reader it is inconsistent. + */ + WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1); + WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1); + smp_wmb(); +} + +static __always_inline void vdso_write_end(struct vdso_data *vd) +{ + smp_wmb(); + /* + * WRITE_ONCE it is required otherwise the compiler can validly tear + * updates to vd[x].seq and it is possible that the value seen by the + * reader it is inconsistent. + */ + WRITE_ONCE(vd[CS_HRES_COARSE].seq, vd[CS_HRES_COARSE].seq + 1); + WRITE_ONCE(vd[CS_RAW].seq, vd[CS_RAW].seq + 1); +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* __VDSO_HELPERS_H */ |