diff mbox series

[1/2] trace-cmd record: Add --subbuf-size option

Message ID 20240110230303.118668-2-rostedt@goodmis.org (mailing list archive)
State Accepted
Commit b424518e9e6216e465ebc2de1ec0492318063921
Headers show
Series trace-cmd record: Add updates for subbuffer size | expand

Commit Message

Steven Rostedt Jan. 10, 2024, 11 p.m. UTC
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

Add an option that will change the sub-buffer size if the kernel supports
it.

Also change the '-b' option that changes the buffer size to use the
libtracefs helper function: tracefs_instance_set_buffer_size().

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 .../trace-cmd/trace-cmd-record.1.txt          | 15 +++++++
 tracecmd/include/trace-local.h                |  1 +
 tracecmd/trace-record.c                       | 44 ++++++++++++-------
 tracecmd/trace-usage.c                        |  1 +
 4 files changed, 45 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/trace-cmd/trace-cmd-record.1.txt b/Documentation/trace-cmd/trace-cmd-record.1.txt
index f46b2564c73a..7cb652bc3c0c 100644
--- a/Documentation/trace-cmd/trace-cmd-record.1.txt
+++ b/Documentation/trace-cmd/trace-cmd-record.1.txt
@@ -198,6 +198,21 @@  OPTIONS
     inside the kernel. Using "-b 10000" on a machine with 4 CPUs will make
     Ftrace have a total buffer size of 40 Megs.
 
+*--subbuf-size*::
+    The Linux kernel tracing ring buffer is broken up into sub-buffers.
+    These sub-buffers are typically the size of the architecture "page-size".
+    (4096 or x86). An event can only be as big as the data portion of a
+    sub-buffer, but in most cases that's not an issue. But the time the
+    writer takes to switch from one sub-buffer to the next has a bit more
+    overhead than adding events within the sub-buffer. By increasing its
+    size, it will allow bigger events (although that is seldom an issue)
+    but also speed up the tracing itself.
+
+    The downside of larger sub-buffers is that a "read" of the ring buffer
+    will pull the sub-buffer size out of the ring buffer and replace it
+    with a new sub-buffer. This may not have any real impact, but it may
+    change the behavior slightly. Or it may not!
+
 *-B* 'buffer-name'::
     If the kernel supports multiple buffers, this will add a buffer with
     the given name. If the buffer name already exists, that buffer is just
diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index 557b2eb0fb07..03738c518aa8 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -286,6 +286,7 @@  struct buffer_instance {
 	int			tracing_on_init_val;
 	int			tracing_on_fd;
 	int			buffer_size;
+	int			subbuf_size;
 	int			cpu_count;
 
 	int			proxy_fd;
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 3114a6646846..4646d8eb41f6 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -5099,10 +5099,7 @@  static char *get_date_to_ts(void)
 static void set_buffer_size_instance(struct buffer_instance *instance)
 {
 	int buffer_size = instance->buffer_size;
-	char buf[BUFSIZ];
-	char *path;
 	int ret;
-	int fd;
 
 	if (is_guest(instance))
 		return;
@@ -5113,29 +5110,38 @@  static void set_buffer_size_instance(struct buffer_instance *instance)
 	if (buffer_size < 0)
 		die("buffer size must be positive");
 
-	snprintf(buf, BUFSIZ, "%d", buffer_size);
+	ret = tracefs_instance_set_buffer_size(instance->tracefs, buffer_size, -1);
+	if (ret < 0)
+		warning("Can't set buffer size");
+}
 
-	path = tracefs_instance_get_file(instance->tracefs, "buffer_size_kb");
-	fd = open(path, O_WRONLY);
-	if (fd < 0) {
-		warning("can't open %s", path);
-		goto out;
-	}
+static void set_subbuf_size_instance(struct buffer_instance *instance)
+{
+	int subbuf_size = instance->subbuf_size;
+	int ret;
+
+	if (is_guest(instance))
+		return;
+
+	if (!subbuf_size)
+		return;
+
+	if (subbuf_size < 0)
+		die("sub-buffer size must be positive");
 
-	ret = write(fd, buf, strlen(buf));
+	ret = tracefs_instance_set_subbuf_size(instance->tracefs, subbuf_size);
 	if (ret < 0)
-		warning("Can't write to %s", path);
-	close(fd);
- out:
-	tracefs_put_tracing_file(path);
+		warning("Can't set sub-buffer size");
 }
 
 void set_buffer_size(void)
 {
 	struct buffer_instance *instance;
 
-	for_all_instances(instance)
+	for_all_instances(instance) {
 		set_buffer_size_instance(instance);
+		set_subbuf_size_instance(instance);
+	}
 }
 
 static int
@@ -5916,6 +5922,7 @@  enum {
 	OPT_temp		= 262,
 	OPT_notimeout		= 264,
 	OPT_daemonize		= 265,
+	OPT_subbuf		= 266,
 };
 
 void trace_stop(int argc, char **argv)
@@ -6343,6 +6350,7 @@  static void parse_record_options(int argc,
 			{"file-version", required_argument, NULL, OPT_file_ver},
 			{"proxy", required_argument, NULL, OPT_proxy},
 			{"temp", required_argument, NULL, OPT_temp},
+			{"subbuf-size", required_argument, NULL, OPT_subbuf},
 			{"daemonize", no_argument, NULL, OPT_daemonize},
 			{NULL, 0, NULL, 0}
 		};
@@ -6829,6 +6837,10 @@  static void parse_record_options(int argc,
 				die("TSC to nanosecond is not supported");
 			ctx->instance->flags |= BUFFER_FL_TSC2NSEC;
 			break;
+		case OPT_subbuf:
+			check_instance_die(ctx->instance, "--subbuf-size");
+			ctx->instance->subbuf_size = atoi(optarg);
+			break;
 		case OPT_poll:
 			cmd_check_die(ctx, CMD_set, *(argv+1), "--poll");
 			recorder_flags |= TRACECMD_RECORD_POLL;
diff --git a/tracecmd/trace-usage.c b/tracecmd/trace-usage.c
index 61acce5f18d2..6944a2c7cf29 100644
--- a/tracecmd/trace-usage.c
+++ b/tracecmd/trace-usage.c
@@ -55,6 +55,7 @@  static struct usage_help usage_help[] = {
 		"          -G when profiling, set soft and hard irqs as global\n"
 		"          --quiet print no output to the screen\n"
 		"          --temp specify a directory to store the temp files used to create trace.dat\n"
+		"          --subbuf-size to specify the sub-buffer size in kilobytes\n"
 		"          --module filter module name\n"
 		"          --by-comm used with --profile, merge events for related comms\n"
 		"          --profile enable tracing options needed for report --profile\n"