aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2023-12-28 16:52:13 -0500
committerSteven Rostedt (Google) <rostedt@goodmis.org>2023-12-28 19:17:54 -0500
commit8c57eb4c8d5385b22eedc7d41f1fd9080ae60efb (patch)
tree22bd3af4e3582681adad2d557e9006aa3e6eba83
parent9bafb21c1e1e5e8f088951f74c641a6aaa9a8236 (diff)
downloadlibtracefs-8c57eb4c8d5385b22eedc7d41f1fd9080ae60efb.tar.gz
libtracefs: Add tracefs_instance_set/get_subbuf_size()
Add API to retrieve and modify the current sub-buffer size. tracefs_instance_set_subbuf_size() tracefs_instance_get_subbuf_size() Link: https://lore.kernel.org/linux-trace-devel/20231228215433.54854-19-rostedt@goodmis.org Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r--Documentation/libtracefs-instances-subbuf.txt152
-rw-r--r--Documentation/libtracefs.txt4
-rw-r--r--include/tracefs.h2
-rw-r--r--samples/Makefile1
-rw-r--r--src/tracefs-instance.c37
5 files changed, 196 insertions, 0 deletions
diff --git a/Documentation/libtracefs-instances-subbuf.txt b/Documentation/libtracefs-instances-subbuf.txt
new file mode 100644
index 0000000..8d5c3e0
--- /dev/null
+++ b/Documentation/libtracefs-instances-subbuf.txt
@@ -0,0 +1,152 @@
+libtracefs(3)
+=============
+
+NAME
+----
+tracefs_instance_get_subbuf_size, tracefs_instance_set_subbuf_size - Helper functions for working with ring buffer sub buffers.
+
+SYNOPSIS
+--------
+[verse]
+--
+*#include <tracefs.h>*
+
+size_t *tracefs_instance_get_subbuf_size*(struct tracefs_instance pass:[*]_instance_);
+int *tracefs_instance_set_subbuf_size*(struct tracefs_instance pass:[*]_instance_, size_t _size_);
+--
+
+DESCRIPTION
+-----------
+Helper functions for working with the sub-buffers of the tracing ring buffer.
+The tracing ring buffer is broken up into *sub-buffers*. An event can not be
+bigger than the data section of the sub-buffer (see *tep_get_sub_buffer_data_size*(3)).
+By default, the ring buffer uses the architectures *page_size* as the default
+size of the sub-buffer, but this can be limiting if there is a need for large
+events, for example, the application wants to write large strings into
+the trace_marker file.
+
+The *tracefs_instance_get_subbuf_size()* returns the current size in kilobytes
+fo the ring buffer sub-buffers.
+
+The *tracefs_instance_set_subbuf_size()* will write the size in kilobytes of
+what the new sub-buffer size should be. Note, that this is only a hint to what
+the minimum sub-buffer size should be. It also does not take into account the
+meta-data that is used by the sub-buffer, so the size written should be no less
+than 16 bytes more than the maximum event size that will be used. The kernel
+will likely make the sub-buffer size larger than specified, as it may need to
+align the size for implementation purposes.
+
+RETURN VALUE
+------------
+The *tracefs_instance_get_subbuf_size()* returns the size of the current
+sub-buffer for the given _instance_ ring buffer or -1 on error.
+
+The *tracefs_instance_set_subbuf_size()* will return 0 if it successfully set
+the _instance_ ring buffer sub-buffer size in kilobytes, or -1 on error.
+
+EXAMPLE
+-------
+[source,c]
+--
+#include <stdlib.h>
+#include <tracefs.h>
+#include <errno.h>
+
+int main(int argc, char **argv)
+{
+ struct tep_handle *tep;
+ ssize_t save_subsize;
+ ssize_t subsize;
+ char *trace;
+ char buf[3000];
+ int meta_size;
+ int ret;
+ int i;
+
+ tep = tep_alloc();
+ ret = tracefs_load_headers(NULL, tep);
+ tep_free(tep);
+
+ if (ret < 0) {
+ perror("reading headers");
+ exit(-1);
+ }
+
+ meta_size = tep_get_sub_buffer_size(tep) - tep_get_sub_buffer_data_size(tep);
+
+ save_subsize = tracefs_instance_get_subbuf_size(NULL);
+ if (save_subsize < 0) {
+ printf("Changing sub-buffer size not available\n");
+ exit(-1);
+ }
+
+ subsize = save_subsize * 1024;
+
+ /* Have at least 4 writes fit on a sub-buffer */
+ if (subsize - meta_size < sizeof(buf) *4 ) {
+ subsize = ((sizeof(buf) * 4 + meta_size) + 1023) / 1024;
+ tracefs_instance_set_subbuf_size(NULL, subsize);
+ }
+
+ for (i = 0; i < sizeof(buf) - 1; i++) {
+ buf[i] = '0' + i % 10;
+ }
+ buf[i] = '\0';
+
+ tracefs_instance_clear(NULL);
+
+ for (i = 0; i < 4; i++) {
+ ret = tracefs_printf(NULL, "%s\n", buf);
+ if (ret < 0)
+ perror("write");
+ }
+
+ trace = tracefs_instance_file_read(NULL, "trace", NULL);
+ printf("%s\n", trace);
+ free(trace);
+
+ printf("Buffer size was: %zd * 1024\n",
+ tracefs_instance_get_subbuf_size(NULL));
+
+ tracefs_instance_set_subbuf_size(NULL, save_subsize);
+}
+--
+FILES
+-----
+[verse]
+--
+*tracefs.h*
+ Header file to include in order to have access to the library APIs.
+*-ltracefs*
+ Linker switch to add when building a program that uses the library.
+--
+
+SEE ALSO
+--------
+*libtracefs*(3),
+*libtraceevent*(3),
+*trace-cmd*(1)
+
+AUTHOR
+------
+[verse]
+--
+*Steven Rostedt* <rostedt@goodmis.org>
+*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>
+--
+REPORTING BUGS
+--------------
+Report bugs to <linux-trace-devel@vger.kernel.org>
+
+LICENSE
+-------
+libtracefs is Free Software licensed under the GNU LGPL 2.1
+
+RESOURCES
+---------
+https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
+
+COPYING
+-------
+Copyright \(C) 2020 VMware, Inc. Free use of this software is granted under
+the terms of the GNU Public License (GPL).
diff --git a/Documentation/libtracefs.txt b/Documentation/libtracefs.txt
index 6752ed3..1962b3b 100644
--- a/Documentation/libtracefs.txt
+++ b/Documentation/libtracefs.txt
@@ -324,6 +324,10 @@ Recording of trace_pipe_raw files:
struct kbuffer pass:[*]*tracefs_cpu_buffered_read_buf*(struct tracefs_cpu pass:[*]_tcpu_, bool _nonblock_);
struct kbuffer pass:[*]*tracefs_cpu_flush_buf*(struct tracefs_cpu pass:[*]_tcpu_);
+Helper functions for modifying the ring buffer sub-buffers:
+ size_t *tracefs_instance_get_subbuf_size*(struct tracefs_instance pass:[*]_instance_);
+ int *tracefs_instance_set_subbuf_size*(struct tracefs_instance pass:[*]_instance_, size_t _size_);
+
Helper functions for guest tracing:
char pass:[*]*tracefs_find_cid_pid*(int _cid_);
char pass:[*]*tracefs_instance_find_cid_pid*(struct tracefs_instance pass:[*]_instance_, int _cid_);
diff --git a/include/tracefs.h b/include/tracefs.h
index 3ae78d4..c66bfd2 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -63,6 +63,8 @@ int tracefs_instance_get_affinity_set(struct tracefs_instance *instance,
cpu_set_t *set, size_t set_size);
ssize_t tracefs_instance_get_buffer_size(struct tracefs_instance *instance, int cpu);
int tracefs_instance_set_buffer_size(struct tracefs_instance *instance, size_t size, int cpu);
+ssize_t tracefs_instance_get_subbuf_size(struct tracefs_instance *instance);
+int tracefs_instance_set_subbuf_size(struct tracefs_instance *instance, size_t size);
char **tracefs_instances(const char *regex);
int tracefs_instance_get_buffer_percent(struct tracefs_instance *instance);
diff --git a/samples/Makefile b/samples/Makefile
index 787d287..77739c8 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -25,6 +25,7 @@ EXAMPLES += cpu
EXAMPLES += guest
EXAMPLES += cpu-buf
EXAMPLES += instances-stat
+EXAMPLES += instances-subbuf
TARGETS :=
TARGETS += sqlhist
diff --git a/src/tracefs-instance.c b/src/tracefs-instance.c
index 2162424..8d9dd0e 100644
--- a/src/tracefs-instance.c
+++ b/src/tracefs-instance.c
@@ -442,6 +442,43 @@ int tracefs_instance_set_buffer_size(struct tracefs_instance *instance, size_t s
}
/**
+ * tracefs_instance_get_subbuf_size - return the sub-buffer size of the ring buffer
+ * @instance: The instance to get the buffer size from
+ *
+ * Returns the sub-buffer size in kilobytes.
+ * Returns -1 on error.
+ */
+ssize_t tracefs_instance_get_subbuf_size(struct tracefs_instance *instance)
+{
+ long long size;
+ int ret;
+
+ ret = tracefs_instance_file_read_number(instance, "buffer_subbuf_size_kb", &size);
+ if (ret < 0)
+ return ret;
+
+ return size;
+}
+
+/**
+ * tracefs_instance_set_buffer_size - modify the ring buffer sub-buffer size
+ * @instance: The instance to modify (NULL for the top level)
+ * @size: The size in kilobytes to to set the sub-buffer size to
+ *
+ * Sets the sub-buffer size in kilobytes for the given ring buffer.
+ *
+ * Returns 0 on success and -1 on error.
+ */
+int tracefs_instance_set_subbuf_size(struct tracefs_instance *instance, size_t size)
+{
+ int ret;
+
+ ret = tracefs_instance_file_write_number(instance, "buffer_subbuf_size_kb", size);
+
+ return ret < 0 ? -1 : 0;
+}
+
+/**
* tracefs_instance_get_trace_dir - return the top trace directory, where the instance is confuigred
* @instance: ftrace instance
*