• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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