ring_buffer_ext.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _LINUX_RING_BUFFER_EXT_H
  3. #define _LINUX_RING_BUFFER_EXT_H
  4. #include <linux/mm.h>
  5. #include <linux/types.h>
  6. struct rb_ext_stats {
  7. u64 entries;
  8. unsigned long pages_touched;
  9. unsigned long overrun;
  10. };
  11. #define RB_PAGE_FT_HEAD (1 << 0)
  12. #define RB_PAGE_FT_READER (1 << 1)
  13. #define RB_PAGE_FT_COMMIT (1 << 2)
  14. /*
  15. * The pages where the events are stored are the only shared elements between
  16. * the reader and the external writer. They are convenient to enable
  17. * communication from the writer to the reader. The data will be used by the
  18. * reader to update its view on the ring buffer.
  19. */
  20. struct rb_ext_page_footer {
  21. atomic_t writer_status;
  22. atomic_t reader_status;
  23. struct rb_ext_stats stats;
  24. };
  25. static inline struct rb_ext_page_footer *rb_ext_page_get_footer(void *page)
  26. {
  27. struct rb_ext_page_footer *footer;
  28. unsigned long page_va = (unsigned long)page;
  29. page_va = ALIGN_DOWN(page_va, PAGE_SIZE);
  30. return (struct rb_ext_page_footer *)(page_va + PAGE_SIZE -
  31. sizeof(*footer));
  32. }
  33. #define BUF_EXT_PAGE_SIZE (BUF_PAGE_SIZE - sizeof(struct rb_ext_page_footer))
  34. /*
  35. * An external writer can't rely on the internal struct ring_buffer_per_cpu.
  36. * Instead, allow to pack the relevant information into struct
  37. * ring_buffer_pack which can be sent to the writer. The latter can then create
  38. * its own view on the ring buffer.
  39. */
  40. struct ring_buffer_pack {
  41. int cpu;
  42. unsigned long reader_page_va;
  43. unsigned long nr_pages;
  44. unsigned long page_va[];
  45. };
  46. struct trace_buffer_pack {
  47. int nr_cpus;
  48. unsigned long total_pages;
  49. char __data[]; /* contains ring_buffer_pack */
  50. };
  51. static inline
  52. struct ring_buffer_pack *__next_ring_buffer_pack(struct ring_buffer_pack *rb_pack)
  53. {
  54. size_t len;
  55. len = offsetof(struct ring_buffer_pack, page_va) +
  56. sizeof(unsigned long) * rb_pack->nr_pages;
  57. return (struct ring_buffer_pack *)((void *)rb_pack + len);
  58. }
  59. /*
  60. * Accessor for ring_buffer_pack's within trace_buffer_pack
  61. */
  62. #define for_each_ring_buffer_pack(rb_pack, cpu, trace_pack) \
  63. for (rb_pack = (struct ring_buffer_pack *)&trace_pack->__data[0], cpu = 0; \
  64. cpu < trace_pack->nr_cpus; \
  65. cpu++, rb_pack = __next_ring_buffer_pack(rb_pack))
  66. #endif