ring_buffer.h 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #ifndef _TOOLS_LINUX_RING_BUFFER_H_
  2. #define _TOOLS_LINUX_RING_BUFFER_H_
  3. #include <asm/barrier.h>
  4. /*
  5. * Contract with kernel for walking the perf ring buffer from
  6. * user space requires the following barrier pairing (quote
  7. * from kernel/events/ring_buffer.c):
  8. *
  9. * Since the mmap() consumer (userspace) can run on a
  10. * different CPU:
  11. *
  12. * kernel user
  13. *
  14. * if (LOAD ->data_tail) { LOAD ->data_head
  15. * (A) smp_rmb() (C)
  16. * STORE $data LOAD $data
  17. * smp_wmb() (B) smp_mb() (D)
  18. * STORE ->data_head STORE ->data_tail
  19. * }
  20. *
  21. * Where A pairs with D, and B pairs with C.
  22. *
  23. * In our case A is a control dependency that separates the
  24. * load of the ->data_tail and the stores of $data. In case
  25. * ->data_tail indicates there is no room in the buffer to
  26. * store $data we do not.
  27. *
  28. * D needs to be a full barrier since it separates the data
  29. * READ from the tail WRITE.
  30. *
  31. * For B a WMB is sufficient since it separates two WRITEs,
  32. * and for C an RMB is sufficient since it separates two READs.
  33. *
  34. * Note, instead of B, C, D we could also use smp_store_release()
  35. * in B and D as well as smp_load_acquire() in C.
  36. *
  37. * However, this optimization does not make sense for all kernel
  38. * supported architectures since for a fair number it would
  39. * resolve into READ_ONCE() + smp_mb() pair for smp_load_acquire(),
  40. * and smp_mb() + WRITE_ONCE() pair for smp_store_release().
  41. *
  42. * Thus for those smp_wmb() in B and smp_rmb() in C would still
  43. * be less expensive. For the case of D this has either the same
  44. * cost or is less expensive, for example, due to TSO x86 can
  45. * avoid the CPU barrier entirely.
  46. */
  47. static inline u64 ring_buffer_read_head(struct perf_event_mmap_page *base)
  48. {
  49. /*
  50. * Architectures where smp_load_acquire() does not fallback to
  51. * READ_ONCE() + smp_mb() pair.
  52. */
  53. #if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
  54. defined(__ia64__) || defined(__sparc__) && defined(__arch64__)
  55. return smp_load_acquire(&base->data_head);
  56. #else
  57. u64 head = READ_ONCE(base->data_head);
  58. smp_rmb();
  59. return head;
  60. #endif
  61. }
  62. static inline void ring_buffer_write_tail(struct perf_event_mmap_page *base,
  63. u64 tail)
  64. {
  65. smp_store_release(&base->data_tail, tail);
  66. }
  67. #endif /* _TOOLS_LINUX_RING_BUFFER_H_ */