linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] libtracefs: Updates to tracefs_tracer_set()
@ 2021-06-25 22:17 Steven Rostedt
  2021-06-25 22:17 ` [PATCH 1/4] libtracefs: Add custom tracer " Steven Rostedt
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Steven Rostedt @ 2021-06-25 22:17 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Sameeruddin shaik, Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Make tracefs_tracer_set() have an optional argument to allow for custom
tracers, for newer or custom kernels.

Update errno values.

Cleanups and documenation.

This is based on top of Sameer's patch:

  https://patchwork.kernel.org/project/linux-trace-devel/patch/1621351602-3703-1-git-send-email-sameeross1994@gmail.com/

Steven Rostedt (VMware) (4):
  libtracefs: Add custom tracer to tracefs_tracer_set()
  libtracefs: Fix the errno values of tracefs_tracer_set()
  libtracefs: Check tracer parameter first in tracefs_tracer_set()
  libtracefs: Add documentation for tracefs_tracer_set/clear()

 Documentation/libtracefs-tracer.txt | 221 ++++++++++++++++++++++++++++
 include/tracefs.h                   |   3 +-
 src/tracefs-tools.c                 |  46 ++++--
 3 files changed, 258 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/libtracefs-tracer.txt

-- 
2.30.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] libtracefs: Add custom tracer to tracefs_tracer_set()
  2021-06-25 22:17 [PATCH 0/4] libtracefs: Updates to tracefs_tracer_set() Steven Rostedt
@ 2021-06-25 22:17 ` Steven Rostedt
  2021-06-25 22:17 ` [PATCH 2/4] libtracefs: Fix the errno values of tracefs_tracer_set() Steven Rostedt
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2021-06-25 22:17 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Sameeruddin shaik, Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Allow the user to enter their own string to define a tracer using
TRACEFS_TRACER_CUSTOM. This way if there's a tracer that is not yet
supported by libtracefs, the user could still enable the tracer with the
tracefs_tracer_set() functionality, as well as use the enums to set
tracers.

 For example:

   tracefs_tracer_set(NULL, TRACEFS_TRACER_CUSTOM, "osnoise");

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/tracefs.h   |  3 ++-
 src/tracefs-tools.c | 28 +++++++++++++++++++++++-----
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/tracefs.h b/include/tracefs.h
index 50873f3..75905ec 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -186,6 +186,7 @@ void tracefs_set_loglevel(enum tep_loglevel level);
 
 enum tracefs_tracers {
 	TRACEFS_TRACER_NOP = 0,
+	TRACEFS_TRACER_CUSTOM,
 	TRACEFS_TRACER_FUNCTION,
 	TRACEFS_TRACER_FUNCTION_GRAPH,
 	TRACEFS_TRACER_IRQSOFF,
@@ -200,7 +201,7 @@ enum tracefs_tracers {
 	TRACEFS_TRACER_BLOCK,
 };
 
-int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers tracer);
+int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers tracer, ...);
 
 int tracefs_tracer_clear(struct tracefs_instance *instance);
 #endif /* _TRACE_FS_H */
diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c
index 21efa6e..fb243d8 100644
--- a/src/tracefs-tools.c
+++ b/src/tracefs-tools.c
@@ -7,6 +7,7 @@
  *
  */
 #include <stdlib.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
@@ -29,6 +30,7 @@ __hidden pthread_mutex_t toplevel_lock = PTHREAD_MUTEX_INITIALIZER;
 
 #define TRACERS \
 	C(NOP,                  "nop"),			\
+	C(CUSTOM,		"CUSTOM"),		\
 	C(FUNCTION,             "function"),            \
 	C(FUNCTION_GRAPH,       "function_graph"),      \
 	C(IRQSOFF,              "irqsoff"),             \
@@ -950,11 +952,20 @@ int write_tracer(int fd, const char *tracer)
 /**
  * tracefs_set_tracer - function to set the tracer
  * @instance: ftrace instance, can be NULL for top tracing instance
- * @tracer: Tracer that has to be set, which can be integer from 0 - 12
- * or enum value
+ * @tracer: The tracer enum that defines the tracer to be set
+ * @t: A tracer name if TRACEFS_TRACER_CUSTOM is passed in for @tracer
+ *
+ * Set the tracer for the instance based on the tracefs_tracer enums.
+ * If the user wishes to enable a tracer that is not defined by
+ * the enum (new or custom kernel), the tracer can be set to
+ * TRACEFS_TRACER_CUSTOM, and pass in a const char * name for
+ * the tracer to set.
+ *
+ * Returns 0 on succes, negative on error.
  */
 
-int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers tracer)
+int tracefs_tracer_set(struct tracefs_instance *instance,
+		       enum tracefs_tracers tracer, ...)
 {
 	char *tracer_path = NULL;
 	const char *t = NULL;
@@ -976,9 +987,16 @@ int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers t
 		errno = -ENODEV;
 		goto out;
 	}
-	if (tracer == tracer_enums[tracer])
+
+	if (tracer == TRACEFS_TRACER_CUSTOM) {
+		va_list ap;
+
+		va_start(ap, tracer);
+		t = va_arg(ap, const char *);
+		va_end(ap);
+	} else if (tracer == tracer_enums[tracer]) {
 		t = tracers[tracer];
-	else {
+	} else {
 		for (i = 0; i < ARRAY_SIZE(tracer_enums); i++) {
 			if (tracer == tracer_enums[i]) {
 				t = tracers[i];
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] libtracefs: Fix the errno values of tracefs_tracer_set()
  2021-06-25 22:17 [PATCH 0/4] libtracefs: Updates to tracefs_tracer_set() Steven Rostedt
  2021-06-25 22:17 ` [PATCH 1/4] libtracefs: Add custom tracer " Steven Rostedt
@ 2021-06-25 22:17 ` Steven Rostedt
  2021-06-25 22:17 ` [PATCH 3/4] libtracefs: Check tracer parameter first in tracefs_tracer_set() Steven Rostedt
  2021-06-25 22:17 ` [PATCH 4/4] libtracefs: Add documentation for tracefs_tracer_set/clear() Steven Rostedt
  3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2021-06-25 22:17 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Sameeruddin shaik, Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Be consistent with the errno values on error for tracefs_tracer_set(). If
a bad enum is passed in, then EINVAL should be set, not ENODEV. But if the
tracer does not exist, then ENODEV should be set (even though the write
will return EINVAL).

Also fix the setting of errno to negative values. That's done in the
kernel, not user space.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 src/tracefs-tools.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c
index fb243d8..6d5ddae 100644
--- a/src/tracefs-tools.c
+++ b/src/tracefs-tools.c
@@ -979,12 +979,12 @@ int tracefs_tracer_set(struct tracefs_instance *instance,
 
 	fd = open(tracer_path, O_WRONLY);
 	if (fd < 0) {
-		errno = -ENOENT;
+		errno = ENOENT;
 		goto out;
 	}
 
 	if (tracer < 0 || tracer > ARRAY_SIZE(tracers)) {
-		errno = -ENODEV;
+		errno = EINVAL;
 		goto out;
 	}
 
@@ -1005,10 +1005,16 @@ int tracefs_tracer_set(struct tracefs_instance *instance,
 		}
 	}
 	if (!t) {
-		errno = -EINVAL;
+		errno = EINVAL;
 		goto out;
 	}
 	ret = write_tracer(fd, t);
+	/*
+	 * If the tracer does not exist, EINVAL is returned,
+	 * but let the user know this as ENODEV.
+	 */
+	if (ret < 0 && errno == EINVAL)
+		errno = ENODEV;
  out:
 	tracefs_put_tracing_file(tracer_path);
 	close(fd);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] libtracefs: Check tracer parameter first in tracefs_tracer_set()
  2021-06-25 22:17 [PATCH 0/4] libtracefs: Updates to tracefs_tracer_set() Steven Rostedt
  2021-06-25 22:17 ` [PATCH 1/4] libtracefs: Add custom tracer " Steven Rostedt
  2021-06-25 22:17 ` [PATCH 2/4] libtracefs: Fix the errno values of tracefs_tracer_set() Steven Rostedt
@ 2021-06-25 22:17 ` Steven Rostedt
  2021-06-25 22:17 ` [PATCH 4/4] libtracefs: Add documentation for tracefs_tracer_set/clear() Steven Rostedt
  3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2021-06-25 22:17 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Sameeruddin shaik, Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

There's no reason to open the current_tracer file, nor even find its path
before checking if the tracer parameter is valid or not. Instead of
checking that later in the process and then having to "clean up" what has
already been done, check it first, and simply return with error if it is
not valid.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 src/tracefs-tools.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/tracefs-tools.c b/src/tracefs-tools.c
index 6d5ddae..0e689aa 100644
--- a/src/tracefs-tools.c
+++ b/src/tracefs-tools.c
@@ -973,6 +973,11 @@ int tracefs_tracer_set(struct tracefs_instance *instance,
 	int fd = -1;
 	int i;
 
+	if (tracer < 0 || tracer > ARRAY_SIZE(tracers)) {
+		errno = EINVAL;
+		return -1;
+	}
+
 	tracer_path = tracefs_instance_get_file(instance, CUR_TRACER);
 	if (!tracer_path)
 		return -1;
@@ -983,11 +988,6 @@ int tracefs_tracer_set(struct tracefs_instance *instance,
 		goto out;
 	}
 
-	if (tracer < 0 || tracer > ARRAY_SIZE(tracers)) {
-		errno = EINVAL;
-		goto out;
-	}
-
 	if (tracer == TRACEFS_TRACER_CUSTOM) {
 		va_list ap;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] libtracefs: Add documentation for tracefs_tracer_set/clear()
  2021-06-25 22:17 [PATCH 0/4] libtracefs: Updates to tracefs_tracer_set() Steven Rostedt
                   ` (2 preceding siblings ...)
  2021-06-25 22:17 ` [PATCH 3/4] libtracefs: Check tracer parameter first in tracefs_tracer_set() Steven Rostedt
@ 2021-06-25 22:17 ` Steven Rostedt
  3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2021-06-25 22:17 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Sameeruddin shaik, Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Add the man page for tracefs_tracer_set() and tracefs_tracer_clear().

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtracefs-tracer.txt | 221 ++++++++++++++++++++++++++++
 1 file changed, 221 insertions(+)
 create mode 100644 Documentation/libtracefs-tracer.txt

diff --git a/Documentation/libtracefs-tracer.txt b/Documentation/libtracefs-tracer.txt
new file mode 100644
index 0000000..64d99c7
--- /dev/null
+++ b/Documentation/libtracefs-tracer.txt
@@ -0,0 +1,221 @@
+libtracefs(3)
+=============
+
+NAME
+----
+tracefs_tracer_set, tracefs_tracer_clear - Enable or disable a tracer in an instance or the top level
+
+SYNOPSIS
+--------
+[verse]
+--
+*#include <tracefs.h>*
+
+int *tracefs_tracer_set*(struct tracefs_instance pass:[*]_instance_, enum tracefs_tracers _tracer_);
+int *tracefs_tracer_set*(struct tracefs_instance pass:[*]_instance_, enum tracefs_tracers _tracer_, const char pass:[*]_name_);
+int *tracefs_tracer_clear*(struct tracefs_instance pass:[*]_instance_);
+--
+
+DESCRIPTION
+-----------
+*tracefs_tracer_set* enables a tracer in the given instance, defined by the
+_instance_ parameter. If _instance_ is NULL, then the top level instance is
+changed. If _tracer_ is set to _TRACFES_TRACER_CUSTOM_ then a const char pass[*]
+string must be passed in as the third parameter, and that is written into the
+instance to enable the tracer with that name. This is useful for newer or
+custom kernels that contain tracers that are not yet identified by the
+tracefs_tracers enum.
+
+*tracefs_tracer_clear* disables the tracer for the given instance defined by
+the _instance_ variable, or the top level instance if it is NULL.
+This is the same as calling *tracefs_tracer_set* with TRACEFS_TRACER_NOP as
+the _tracer_ parameter.
+
+TRACEFS_TRACER ENUMS
+--------------------
+
+The currently defined enums that are accepted are:
+
+*TRACEFS_TRACER_NOP* :
+This is the idle tracer, which does nothing and is used to clear any
+active tarcer.
+
+*TRACEFS_TRACER_FUNCTION* :
+Enables most functions in the kernel to be traced.
+
+*TRACEFS_TRACER_FUNCTION_GRAPH* :
+Enables most functions in the kernel to be traced as well as the return
+of the function.
+
+*TRACEFS_TRACER_IRQSOFF* :
+Tracers the latency of interrupts disabled.
+
+*TRACEFS_TRACER_PREEMPTOFF* :
+Tracers the latency of preemption disabled (the time in the kernel that
+tasks can not be scheduled from the CPU).
+
+*TRACEFS_TRACER_PREEMPTIRQSOFF* :
+Traces the combined total latency of when interrupts are disabled as well as when
+preemption is disabled.
+
+*TRACEFS_TRACER_WAKEUP* :
+Traces the latency of when the highest priority task takes to wake up.
+
+*TRACEFS_TRACER_WAKEUP_RT* :
+Traces the latency of when the highest priority real-time task takes to wake up.
+All other tasks are ignored.
+
+*TRACEFS_TRACER_WAKEUP_DL* :
+Traces the latency of when the highest priority DEADLINE task takes to wake up.
+All other tasks are ignored.
+
+*TRACEFS_TRACER_MMIOTRACE* :
+Traces the interaction of devices with the kernel.
+
+*TRACEFS_TRACER_HWLAT* :
+Detects latency caused by the hardware that is outside the scope of the kernel.
+
+*TRACEFS_TRACER_BRANCH* :
+Traces when likely or unlikely branches are taken.
+
+*TRACEFS_TRACER_BLOCK* :
+Special tracer for the block devices.
+
+Note that the above tracers may not be available in the kernel and
+*tracefs_tracer_set()* will return an error with errno set to ENODEV,
+if the kernel does not support the _tracer_ option, or the custom one
+if TRACEFS_TRACER_CUSTOM is used.
+
+RETURN VALUE
+------------
+Returns 0 on success, or -1 on error.
+
+ERRORS
+------
+
+*tracefs_tracer_set*() can fail with the following errors:
+
+*EINVAL* The _tracer_ parameter is outside the scope of what is defined.
+
+*ENOMEM* Memory allocation error.
+
+*ENOENT* Tracers are not supported on the running kernel.
+
+*ENODEV* The specified tracer is not supported on the running kernel.
+
+Other errors may also happen caused by internal system calls.
+
+EXAMPLE
+-------
+[source,c]
+--
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <errno.h>
+#include <tracefs.h>
+
+int main(int argc, char *argv[])
+{
+	struct tracefs_instance *inst = NULL;
+	enum tracefs_tracers t = TRACEFS_TRACER_NOP;
+	const char *buf = NULL;
+	const char *cust;
+	int ret;
+	int ch;
+
+	while ((ch = getopt(argc, argv, "nfgiwdc:B:")) > 0) {
+		switch (ch) {
+		case 'f': t = TRACEFS_TRACER_FUNCTION; break;
+		case 'g': t = TRACEFS_TRACER_FUNCTION_GRAPH; break;
+		case 'i': t = TRACEFS_TRACER_PREEMPTIRQSOFF; break;
+		case 'w': t = TRACEFS_TRACER_WAKEUP_RT; break;
+		case 'd': t = TRACEFS_TRACER_WAKEUP_DL; break;
+		case 'c':
+			t = TRACEFS_TRACER_CUSTOM;
+			cust = optarg;
+			break;
+		case 'B':
+			buf = optarg;
+			break;
+		case 'n':
+			/* nop */
+			break;
+		default:
+			printf("Unknow arg %c\n", ch);
+			exit(-1);
+		}
+	}
+
+	if (buf) {
+		inst = tracefs_instance_create(buf);
+		if (!inst) {
+			printf("failed to create instance\n");
+			exit(-1);
+		}
+	}
+
+	if (t == TRACEFS_TRACER_CUSTOM)
+		ret = tracefs_tracer_set(inst, t, cust);
+	else
+		ret = tracefs_tracer_set(inst, t);
+
+	if (ret < 0) {
+		if (inst) {
+			tracefs_instance_destroy(inst);
+			tracefs_instance_free(inst);
+		}
+		if (errno == ENODEV)
+			printf("Tracer not supported by kernel\n");
+		else
+			perror("Error");
+		exit(-1);
+	}
+
+	if (inst)
+		tracefs_instance_free(inst);
+
+	exit(0);
+}
+--
+
+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>
+*sameeruddin shaik* <sameeruddin.shaik8@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).
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-06-25 22:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-25 22:17 [PATCH 0/4] libtracefs: Updates to tracefs_tracer_set() Steven Rostedt
2021-06-25 22:17 ` [PATCH 1/4] libtracefs: Add custom tracer " Steven Rostedt
2021-06-25 22:17 ` [PATCH 2/4] libtracefs: Fix the errno values of tracefs_tracer_set() Steven Rostedt
2021-06-25 22:17 ` [PATCH 3/4] libtracefs: Check tracer parameter first in tracefs_tracer_set() Steven Rostedt
2021-06-25 22:17 ` [PATCH 4/4] libtracefs: Add documentation for tracefs_tracer_set/clear() Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).