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