vvar.h (1577B)
1/* 2 * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. 3 */ 4 5#ifndef _ASM_SPARC_VVAR_DATA_H 6#define _ASM_SPARC_VVAR_DATA_H 7 8#include <asm/clocksource.h> 9#include <asm/processor.h> 10#include <asm/barrier.h> 11#include <linux/time.h> 12#include <linux/types.h> 13 14struct vvar_data { 15 unsigned int seq; 16 17 int vclock_mode; 18 struct { /* extract of a clocksource struct */ 19 u64 cycle_last; 20 u64 mask; 21 int mult; 22 int shift; 23 } clock; 24 /* open coded 'struct timespec' */ 25 u64 wall_time_sec; 26 u64 wall_time_snsec; 27 u64 monotonic_time_snsec; 28 u64 monotonic_time_sec; 29 u64 monotonic_time_coarse_sec; 30 u64 monotonic_time_coarse_nsec; 31 u64 wall_time_coarse_sec; 32 u64 wall_time_coarse_nsec; 33 34 int tz_minuteswest; 35 int tz_dsttime; 36}; 37 38extern struct vvar_data *vvar_data; 39extern int vdso_fix_stick; 40 41static inline unsigned int vvar_read_begin(const struct vvar_data *s) 42{ 43 unsigned int ret; 44 45repeat: 46 ret = READ_ONCE(s->seq); 47 if (unlikely(ret & 1)) { 48 cpu_relax(); 49 goto repeat; 50 } 51 smp_rmb(); /* Finish all reads before we return seq */ 52 return ret; 53} 54 55static inline int vvar_read_retry(const struct vvar_data *s, 56 unsigned int start) 57{ 58 smp_rmb(); /* Finish all reads before checking the value of seq */ 59 return unlikely(s->seq != start); 60} 61 62static inline void vvar_write_begin(struct vvar_data *s) 63{ 64 ++s->seq; 65 smp_wmb(); /* Makes sure that increment of seq is reflected */ 66} 67 68static inline void vvar_write_end(struct vvar_data *s) 69{ 70 smp_wmb(); /* Makes the value of seq current before we increment */ 71 ++s->seq; 72} 73 74 75#endif /* _ASM_SPARC_VVAR_DATA_H */