'\" t
.\" Title: libtracefs
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 01/13/2024
.\" Manual: libtracefs Manual
.\" Source: libtracefs 1.8.0
.\" Language: English
.\"
.TH "LIBTRACEFS" "3" "01/13/2024" "libtracefs 1\&.8\&.0" "libtracefs Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
tracefs_cpu_open_mapped, tracefs_cpu_is_mapped, tracefs_mapped_is_supported, tracefs_cpu_map, tracefs_cpu_unmap \- Memory mapping of the ring buffer
.SH "SYNOPSIS"
.sp
.nf
\fB#include \fR
bool \fBtracefs_cpu_is_mapped\fR(struct tracefs_cpu *tcpu);
bool \fBtracefs_mapped_is_supported\fR(void);
int \fBtracefs_cpu_map\fR(struct tracefs_cpu *tcpu);
void \fBtracefs_cpu_unmap\fR(struct tracefs_cpu *tcpu);
struct tracefs_cpu *\fBtracefs_cpu_open_mapped\fR(struct tracefs_instance *instance,
int cpu, bool nonblock);
.fi
.SH "DESCRIPTION"
.sp
If the trace_pipe_raw supports memory mapping, this is usually a more efficient method to stream data from the kernel ring buffer than by reading it, as it does not require copying the memory that is being read\&.
.sp
If memory mapping is supported by the kernel and the application asks to use the memory mapping via either \fBtracefs_cpu_map()\fR or by \fBtracefs_cpu_open_mapped()\fR then the functions \fBtracefs_cpu_read\fR(3) and \fBtracefs_cpu_read_buf\fR(3) will use the mapping directly instead of calling the read system call\&.
.sp
Note, mapping will cause \fBtracefs_cpu_buffered_read\fR(3) and \fBtracefs_cpu_buffered_read_buf\fR(3) to act just like \fBtracefs_cpu_read\fR(3) and \fBtracefs_cpu_read_buf\fR(3) respectively as it doesn\(cqt make sense to use a splice pipe when mapped\&. The kernel will do a copy for splice reads on mapping, and then another copy in the function when it can avoid the copying if the ring buffer is memory mapped\&.
.sp
If the \fItcpu\fR is memory mapped it will also force \fBtracefs_cpu_write\fR(3) and \fBtracefs_cpu_pipe\fR(3) to copy from the mapping instead of using splice\&. Thus care must be used when determining to map the ring buffer or not, and why it does not get mapped by default\&.
.sp
The \fBtracefs_cpu_is_mapped()\fR function will return true if \fItcpu\fR currently has its ring buffer memory mapped and false otherwise\&. This does not return whether or not that the kernel supports memory mapping, but that can usually be determined by calling \fBtracefs_cpu_map()\fR\&.
.sp
The \fBtracefs_mapped_is_supported()\fR returns true if the ring buffer can be memory mapped\&.
.sp
The \fBtracefs_cpu_map()\fR function will attempt to map the ring buffer associated to \fItcpu\fR if it is not already mapped\&.
.sp
The \fBtracefs_cpu_unmap()\fR function will unmap the ring buffer associated to \fItcpu\fR if it is mapped\&.
.sp
The \fBtracefs_cpu_open_mapped()\fR is equivalent to calling \fBtracefs_cpu_open\fR(3) followed by \fBtracefs_cpu_map()\fR on the returned \fItcpu\fR of \fBtracefs_cpu_open\fR(3)\&. Note, this will still succeed if the mapping fails, in which case it acts the same as \fBtracefs_cpu_open\fR(3)\&. If knowing if the mapping succeed or not, \fBtracefs_cpu_is_mapped()\fR should be called on the return \fItcpu\fR\&.
.SH "RETURN VALUE"
.sp
\fBtracefs_cpu_is_mapped()\fR returns true if the given \fItcpu\fR has its ring buffer memory mapped or false otherwise\&.
.sp
\fBtracefs_mapped_is_supported()\fR returns true if the tracing ring buffer can be memory mapped or false if it cannot be or an error occurred\&.
.sp
\fBtracefs_cpu_map()\fR returns 0 on success and \-1 on error in mapping\&. If 0 is returned then \fBtracefs_cpu_is_mapped()\fR will return true afterward, or false if the mapping failed\&.
.sp
\fBtracefs_cpu_open_mapped()\fR returns an allocated tracefs_cpu on success of creation regardless if it succeed in mapping the ring buffer or not\&. It returns NULL for the same reasons \fBtracefs_cpu_open\fR(3) returns NULL\&. If success of mapping is to be known, then calling \fBtracefs_cpu_is_mapped()\fR afterward is required\&.
.SH "EXAMPLE"
.sp
.if n \{\
.RS 4
.\}
.nf
#include
#include
#include
static void read_subbuf(struct tep_handle *tep, struct kbuffer *kbuf)
{
static struct trace_seq seq;
struct tep_record record;
int missed_events;
if (seq\&.buffer)
trace_seq_reset(&seq);
else
trace_seq_init(&seq);
while ((record\&.data = kbuffer_read_event(kbuf, &record\&.ts))) {
record\&.size = kbuffer_event_size(kbuf);
missed_events = kbuffer_missed_events(kbuf);
if (missed_events) {
printf("[MISSED EVENTS");
if (missed_events > 0)
printf(": %d]\en", missed_events);
else
printf("]\en");
}
kbuffer_next_event(kbuf, NULL);
tep_print_event(tep, &seq, &record,
"%s\-%d %6\&.1000d\et%s: %s\en",
TEP_PRINT_COMM,
TEP_PRINT_PID,
TEP_PRINT_TIME,
TEP_PRINT_NAME,
TEP_PRINT_INFO);
trace_seq_do_printf(&seq);
trace_seq_reset(&seq);
}
}
int main (int argc, char **argv)
{
struct tracefs_cpu *tcpu;
struct tep_handle *tep;
struct kbuffer *kbuf;
bool mapped;
int cpu;
if (argc < 2 || !isdigit(argv[1][0])) {
printf("usage: %s cpu\en\en", argv[0]);
exit(\-1);
}
cpu = atoi(argv[1]);
tep = tracefs_local_events(NULL);
if (!tep) {
perror("Reading trace event formats");
exit(\-1);
}
tcpu = tracefs_cpu_open_mapped(NULL, cpu, 0);
if (!tcpu) {
perror("Open CPU 0 file");
exit(\-1);
}
/*
* If this kernel supports mapping, use normal read,
* otherwise use the piped buffer read, although if
* the mapping succeeded, tracefs_cpu_buffered_read_buf()
* acts the same as tracefs_cpu_read_buf()\&. But this is just
* an example on how to use tracefs_cpu_is_mapped()\&.
*/
mapped = tracefs_cpu_is_mapped(tcpu);
if (!mapped)
printf("Was not able to map, falling back to buffered read\en");
while ((kbuf = mapped ? tracefs_cpu_read_buf(tcpu, true) :
tracefs_cpu_buffered_read_buf(tcpu, true))) {
read_subbuf(tep, kbuf);
}
kbuf = tracefs_cpu_flush_buf(tcpu);
if (kbuf)
read_subbuf(tep, kbuf);
tracefs_cpu_close(tcpu);
tep_free(tep);
return 0;
}
.fi
.if n \{\
.RE
.\}
.SH "FILES"
.sp
.if n \{\
.RS 4
.\}
.nf
\fBtracefs\&.h\fR
Header file to include in order to have access to the library APIs\&.
\fB\-ltracefs\fR
Linker switch to add when building a program that uses the library\&.
.fi
.if n \{\
.RE
.\}
.SH "SEE ALSO"
.sp
\fBtracefs_cpu_open\fR(3), \fBtracefs_cpu_read\fR(3), \fBtracefs_cpu_read_buf\fR(3), \fBtracefs_cpu_buffered_read\fR(3), \fBtracefs_cpu_buffered_read_buf\fR(3), \fBlibtracefs\fR(3), \fBlibtraceevent\fR(3), \fBtrace\-cmd\fR(1)
.SH "AUTHOR"
.sp
.if n \{\
.RS 4
.\}
.nf
\fBSteven Rostedt\fR <\m[blue]\fBrostedt@goodmis\&.org\fR\m[]\&\s-2\u[1]\d\s+2>
.fi
.if n \{\
.RE
.\}
.SH "REPORTING BUGS"
.sp
Report bugs to <\m[blue]\fBlinux\-trace\-devel@vger\&.kernel\&.org\fR\m[]\&\s-2\u[2]\d\s+2>
.SH "LICENSE"
.sp
libtracefs is Free Software licensed under the GNU LGPL 2\&.1
.SH "RESOURCES"
.sp
\m[blue]\fBhttps://git\&.kernel\&.org/pub/scm/libs/libtrace/libtracefs\&.git/\fR\m[]
.SH "COPYING"
.sp
Copyright (C) 2022 Google, Inc\&. Free use of this software is granted under the terms of the GNU Public License (GPL)\&.
.SH "NOTES"
.IP " 1." 4
rostedt@goodmis.org
.RS 4
\%mailto:rostedt@goodmis.org
.RE
.IP " 2." 4
linux-trace-devel@vger.kernel.org
.RS 4
\%mailto:linux-trace-devel@vger.kernel.org
.RE