1libtracefs(3) 2============= 3 4NAME 5---- 6tracefs_cpu_open_mapped, tracefs_cpu_is_mapped, tracefs_mapped_is_supported, tracefs_cpu_map, tracefs_cpu_unmap - Memory mapping of the ring buffer 7 8SYNOPSIS 9-------- 10[verse] 11-- 12*#include <tracefs.h>* 13 14bool *tracefs_cpu_is_mapped*(struct tracefs_cpu pass:[*]tcpu); 15bool *tracefs_mapped_is_supported*(void); 16int *tracefs_cpu_map*(struct tracefs_cpu pass:[*]tcpu); 17void *tracefs_cpu_unmap*(struct tracefs_cpu pass:[*]tcpu); 18struct tracefs_cpu pass:[*]*tracefs_cpu_open_mapped*(struct tracefs_instance pass:[*]instance, 19 int cpu, bool nonblock); 20-- 21 22DESCRIPTION 23----------- 24If the trace_pipe_raw supports memory mapping, this is usually a more efficient 25method to stream data from the kernel ring buffer than by reading it, as it does 26not require copying the memory that is being read. 27 28If memory mapping is supported by the kernel and the application asks to use the 29memory mapping via either *tracefs_cpu_map()* or by *tracefs_cpu_open_mapped()* 30then the functions *tracefs_cpu_read*(3) and *tracefs_cpu_read_buf*(3) will use 31the mapping directly instead of calling the read system call. 32 33Note, mapping will cause *tracefs_cpu_buffered_read*(3) and *tracefs_cpu_buffered_read_buf*(3) 34to act just like *tracefs_cpu_read*(3) and *tracefs_cpu_read_buf*(3) respectively 35as it doesn't make sense to use a splice pipe when mapped. The kernel will do 36a copy for splice reads on mapping, and then another copy in the function when 37it can avoid the copying if the ring buffer is memory mapped. 38 39If the _tcpu_ is memory mapped it will also force *tracefs_cpu_write*(3) and 40*tracefs_cpu_pipe*(3) to copy from the mapping instead of using splice. 41Thus care must be used when determining to map the ring buffer or not, 42and why it does not get mapped by default. 43 44The *tracefs_cpu_is_mapped()* function will return true if _tcpu_ currently has 45its ring buffer memory mapped and false otherwise. This does not return whether or 46not that the kernel supports memory mapping, but that can usually be determined 47by calling *tracefs_cpu_map()*. 48 49The *tracefs_mapped_is_supported()* returns true if the ring buffer can be 50memory mapped. 51 52The *tracefs_cpu_map()* function will attempt to map the ring buffer associated 53to _tcpu_ if it is not already mapped. 54 55The *tracefs_cpu_unmap()* function will unmap the ring buffer associated to 56_tcpu_ if it is mapped. 57 58The *tracefs_cpu_open_mapped()* is equivalent to calling *tracefs_cpu_open*(3) followed 59by *tracefs_cpu_map()* on the returned _tcpu_ of *tracefs_cpu_open*(3). Note, this 60will still succeed if the mapping fails, in which case it acts the same as 61*tracefs_cpu_open*(3). If knowing if the mapping succeed or not, *tracefs_cpu_is_mapped()* 62should be called on the return _tcpu_. 63 64RETURN VALUE 65------------ 66*tracefs_cpu_is_mapped()* returns true if the given _tcpu_ has its ring buffer 67memory mapped or false otherwise. 68 69*tracefs_mapped_is_supported()* returns true if the tracing ring buffer can be 70memory mapped or false if it cannot be or an error occurred. 71 72*tracefs_cpu_map()* returns 0 on success and -1 on error in mapping. If 0 is 73returned then *tracefs_cpu_is_mapped()* will return true afterward, or false 74if the mapping failed. 75 76*tracefs_cpu_open_mapped()* returns an allocated tracefs_cpu on success of creation 77regardless if it succeed in mapping the ring buffer or not. It returns NULL for 78the same reasons *tracefs_cpu_open*(3) returns NULL. If success of mapping is 79to be known, then calling *tracefs_cpu_is_mapped()* afterward is required. 80 81EXAMPLE 82------- 83[source,c] 84-- 85#include <stdlib.h> 86#include <ctype.h> 87#include <tracefs.h> 88 89static void read_subbuf(struct tep_handle *tep, struct kbuffer *kbuf) 90{ 91 static struct trace_seq seq; 92 struct tep_record record; 93 int missed_events; 94 95 if (seq.buffer) 96 trace_seq_reset(&seq); 97 else 98 trace_seq_init(&seq); 99 100 while ((record.data = kbuffer_read_event(kbuf, &record.ts))) { 101 record.size = kbuffer_event_size(kbuf); 102 missed_events = kbuffer_missed_events(kbuf); 103 if (missed_events) { 104 printf("[MISSED EVENTS"); 105 if (missed_events > 0) 106 printf(": %d]\n", missed_events); 107 else 108 printf("]\n"); 109 } 110 kbuffer_next_event(kbuf, NULL); 111 tep_print_event(tep, &seq, &record, 112 "%s-%d %6.1000d\t%s: %s\n", 113 TEP_PRINT_COMM, 114 TEP_PRINT_PID, 115 TEP_PRINT_TIME, 116 TEP_PRINT_NAME, 117 TEP_PRINT_INFO); 118 trace_seq_do_printf(&seq); 119 trace_seq_reset(&seq); 120 } 121} 122 123int main (int argc, char **argv) 124{ 125 struct tracefs_cpu *tcpu; 126 struct tep_handle *tep; 127 struct kbuffer *kbuf; 128 bool mapped; 129 int cpu; 130 131 if (argc < 2 || !isdigit(argv[1][0])) { 132 printf("usage: %s cpu\n\n", argv[0]); 133 exit(-1); 134 } 135 136 cpu = atoi(argv[1]); 137 138 tep = tracefs_local_events(NULL); 139 if (!tep) { 140 perror("Reading trace event formats"); 141 exit(-1); 142 } 143 144 tcpu = tracefs_cpu_open_mapped(NULL, cpu, 0); 145 if (!tcpu) { 146 perror("Open CPU 0 file"); 147 exit(-1); 148 } 149 150 /* 151 * If this kernel supports mapping, use normal read, 152 * otherwise use the piped buffer read, although if 153 * the mapping succeeded, tracefs_cpu_buffered_read_buf() 154 * acts the same as tracefs_cpu_read_buf(). But this is just 155 * an example on how to use tracefs_cpu_is_mapped(). 156 */ 157 mapped = tracefs_cpu_is_mapped(tcpu); 158 if (!mapped) 159 printf("Was not able to map, falling back to buffered read\n"); 160 while ((kbuf = mapped ? tracefs_cpu_read_buf(tcpu, true) : 161 tracefs_cpu_buffered_read_buf(tcpu, true))) { 162 read_subbuf(tep, kbuf); 163 } 164 165 kbuf = tracefs_cpu_flush_buf(tcpu); 166 if (kbuf) 167 read_subbuf(tep, kbuf); 168 169 tracefs_cpu_close(tcpu); 170 tep_free(tep); 171 172 return 0; 173} 174-- 175 176FILES 177----- 178[verse] 179-- 180*tracefs.h* 181 Header file to include in order to have access to the library APIs. 182*-ltracefs* 183 Linker switch to add when building a program that uses the library. 184-- 185 186SEE ALSO 187-------- 188*tracefs_cpu_open*(3), 189*tracefs_cpu_read*(3), 190*tracefs_cpu_read_buf*(3), 191*tracefs_cpu_buffered_read*(3), 192*tracefs_cpu_buffered_read_buf*(3), 193*libtracefs*(3), 194*libtraceevent*(3), 195*trace-cmd*(1) 196 197AUTHOR 198------ 199[verse] 200-- 201*Steven Rostedt* <rostedt@goodmis.org> 202-- 203REPORTING BUGS 204-------------- 205Report bugs to <linux-trace-devel@vger.kernel.org> 206 207LICENSE 208------- 209libtracefs is Free Software licensed under the GNU LGPL 2.1 210 211RESOURCES 212--------- 213https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 214 215COPYING 216------- 217Copyright \(C) 2022 Google, Inc. Free use of this software is granted under 218the terms of the GNU Public License (GPL). 219