12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- /* SPDX-License-Identifier: GPL-2.0 */
- #ifndef _LINUX_RING_BUFFER_EXT_H
- #define _LINUX_RING_BUFFER_EXT_H
- #include <linux/mm.h>
- #include <linux/types.h>
- struct rb_ext_stats {
- u64 entries;
- unsigned long pages_touched;
- unsigned long overrun;
- };
- #define RB_PAGE_FT_HEAD (1 << 0)
- #define RB_PAGE_FT_READER (1 << 1)
- #define RB_PAGE_FT_COMMIT (1 << 2)
- /*
- * The pages where the events are stored are the only shared elements between
- * the reader and the external writer. They are convenient to enable
- * communication from the writer to the reader. The data will be used by the
- * reader to update its view on the ring buffer.
- */
- struct rb_ext_page_footer {
- atomic_t writer_status;
- atomic_t reader_status;
- struct rb_ext_stats stats;
- };
- static inline struct rb_ext_page_footer *rb_ext_page_get_footer(void *page)
- {
- struct rb_ext_page_footer *footer;
- unsigned long page_va = (unsigned long)page;
- page_va = ALIGN_DOWN(page_va, PAGE_SIZE);
- return (struct rb_ext_page_footer *)(page_va + PAGE_SIZE -
- sizeof(*footer));
- }
- #define BUF_EXT_PAGE_SIZE (BUF_PAGE_SIZE - sizeof(struct rb_ext_page_footer))
- /*
- * An external writer can't rely on the internal struct ring_buffer_per_cpu.
- * Instead, allow to pack the relevant information into struct
- * ring_buffer_pack which can be sent to the writer. The latter can then create
- * its own view on the ring buffer.
- */
- struct ring_buffer_pack {
- int cpu;
- unsigned long reader_page_va;
- unsigned long nr_pages;
- unsigned long page_va[];
- };
- struct trace_buffer_pack {
- int nr_cpus;
- unsigned long total_pages;
- char __data[]; /* contains ring_buffer_pack */
- };
- static inline
- struct ring_buffer_pack *__next_ring_buffer_pack(struct ring_buffer_pack *rb_pack)
- {
- size_t len;
- len = offsetof(struct ring_buffer_pack, page_va) +
- sizeof(unsigned long) * rb_pack->nr_pages;
- return (struct ring_buffer_pack *)((void *)rb_pack + len);
- }
- /*
- * Accessor for ring_buffer_pack's within trace_buffer_pack
- */
- #define for_each_ring_buffer_pack(rb_pack, cpu, trace_pack) \
- for (rb_pack = (struct ring_buffer_pack *)&trace_pack->__data[0], cpu = 0; \
- cpu < trace_pack->nr_cpus; \
- cpu++, rb_pack = __next_ring_buffer_pack(rb_pack))
- #endif
|