Commit | Line | Data |
---|---|---|
a1e0dd7c VD |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | ================================== | |
4 | Tracefs ring-buffer memory mapping | |
5 | ================================== | |
6 | ||
7 | :Author: Vincent Donnefort <vdonnefort@google.com> | |
8 | ||
9 | Overview | |
10 | ======== | |
11 | Tracefs ring-buffer memory map provides an efficient method to stream data | |
12 | as no memory copy is necessary. The application mapping the ring-buffer becomes | |
13 | then a consumer for that ring-buffer, in a similar fashion to trace_pipe. | |
14 | ||
15 | Memory mapping setup | |
16 | ==================== | |
17 | The mapping works with a mmap() of the trace_pipe_raw interface. | |
18 | ||
19 | The first system page of the mapping contains ring-buffer statistics and | |
20 | description. It is referred to as the meta-page. One of the most important | |
21 | fields of the meta-page is the reader. It contains the sub-buffer ID which can | |
22 | be safely read by the mapper (see ring-buffer-design.rst). | |
23 | ||
24 | The meta-page is followed by all the sub-buffers, ordered by ascending ID. It is | |
25 | therefore effortless to know where the reader starts in the mapping: | |
26 | ||
27 | .. code-block:: c | |
28 | ||
29 | reader_id = meta->reader->id; | |
30 | reader_offset = meta->meta_page_size + reader_id * meta->subbuf_size; | |
31 | ||
32 | When the application is done with the current reader, it can get a new one using | |
33 | the trace_pipe_raw ioctl() TRACE_MMAP_IOCTL_GET_READER. This ioctl also updates | |
34 | the meta-page fields. | |
35 | ||
36 | Limitations | |
37 | =========== | |
38 | When a mapping is in place on a Tracefs ring-buffer, it is not possible to | |
39 | either resize it (either by increasing the entire size of the ring-buffer or | |
40 | each subbuf). It is also not possible to use snapshot and causes splice to copy | |
41 | the ring buffer data instead of using the copyless swap from the ring buffer. | |
42 | ||
43 | Concurrent readers (either another application mapping that ring-buffer or the | |
44 | kernel with trace_pipe) are allowed but not recommended. They will compete for | |
45 | the ring-buffer and the output is unpredictable, just like concurrent readers on | |
46 | trace_pipe would be. | |
47 | ||
48 | Example | |
49 | ======= | |
50 | ||
51 | .. code-block:: c | |
52 | ||
53 | #include <fcntl.h> | |
54 | #include <stdio.h> | |
55 | #include <stdlib.h> | |
56 | #include <unistd.h> | |
57 | ||
58 | #include <linux/trace_mmap.h> | |
59 | ||
60 | #include <sys/mman.h> | |
61 | #include <sys/ioctl.h> | |
62 | ||
63 | #define TRACE_PIPE_RAW "/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw" | |
64 | ||
65 | int main(void) | |
66 | { | |
67 | int page_size = getpagesize(), fd, reader_id; | |
68 | unsigned long meta_len, data_len; | |
69 | struct trace_buffer_meta *meta; | |
70 | void *map, *reader, *data; | |
71 | ||
72 | fd = open(TRACE_PIPE_RAW, O_RDONLY | O_NONBLOCK); | |
73 | if (fd < 0) | |
74 | exit(EXIT_FAILURE); | |
75 | ||
76 | map = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); | |
77 | if (map == MAP_FAILED) | |
78 | exit(EXIT_FAILURE); | |
79 | ||
80 | meta = (struct trace_buffer_meta *)map; | |
81 | meta_len = meta->meta_page_size; | |
82 | ||
83 | printf("entries: %llu\n", meta->entries); | |
84 | printf("overrun: %llu\n", meta->overrun); | |
85 | printf("read: %llu\n", meta->read); | |
86 | printf("nr_subbufs: %u\n", meta->nr_subbufs); | |
87 | ||
88 | data_len = meta->subbuf_size * meta->nr_subbufs; | |
89 | data = mmap(NULL, data_len, PROT_READ, MAP_SHARED, fd, meta_len); | |
90 | if (data == MAP_FAILED) | |
91 | exit(EXIT_FAILURE); | |
92 | ||
93 | if (ioctl(fd, TRACE_MMAP_IOCTL_GET_READER) < 0) | |
94 | exit(EXIT_FAILURE); | |
95 | ||
96 | reader_id = meta->reader.id; | |
97 | reader = data + meta->subbuf_size * reader_id; | |
98 | ||
99 | printf("Current reader address: %p\n", reader); | |
100 | ||
101 | munmap(data, data_len); | |
102 | munmap(meta, meta_len); | |
103 | close (fd); | |
104 | ||
105 | return 0; | |
106 | } |