vvar.h 1.5 KB

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