Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / Documentation / trace / ring-buffer-map.rst
blob8e296bcc0d7f32c05fd241feb5567cdc03e1cef8
1 .. SPDX-License-Identifier: GPL-2.0
3 ==================================
4 Tracefs ring-buffer memory mapping
5 ==================================
7 :Author: Vincent Donnefort <vdonnefort@google.com>
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.
15 Memory mapping setup
16 ====================
17 The mapping works with a mmap() of the trace_pipe_raw interface.
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).
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:
27 .. code-block:: c
29         reader_id = meta->reader->id;
30         reader_offset = meta->meta_page_size + reader_id * meta->subbuf_size;
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.
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.
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.
48 Example
49 =======
51 .. code-block:: c
53         #include <fcntl.h>
54         #include <stdio.h>
55         #include <stdlib.h>
56         #include <unistd.h>
58         #include <linux/trace_mmap.h>
60         #include <sys/mman.h>
61         #include <sys/ioctl.h>
63         #define TRACE_PIPE_RAW "/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw"
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;
72                 fd = open(TRACE_PIPE_RAW, O_RDONLY | O_NONBLOCK);
73                 if (fd < 0)
74                         exit(EXIT_FAILURE);
76                 map = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
77                 if (map == MAP_FAILED)
78                         exit(EXIT_FAILURE);
80                 meta = (struct trace_buffer_meta *)map;
81                 meta_len = meta->meta_page_size;
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);
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);
93                 if (ioctl(fd, TRACE_MMAP_IOCTL_GET_READER) < 0)
94                         exit(EXIT_FAILURE);
96                 reader_id = meta->reader.id;
97                 reader = data + meta->subbuf_size * reader_id;
99                 printf("Current reader address: %p\n", reader);
101                 munmap(data, data_len);
102                 munmap(meta, meta_len);
103                 close (fd);
105                 return 0;
106         }