summaryrefslogtreecommitdiffstats
path: root/Documentation/libtracefs-synth-info.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/libtracefs-synth-info.txt')
-rw-r--r--Documentation/libtracefs-synth-info.txt298
1 files changed, 298 insertions, 0 deletions
diff --git a/Documentation/libtracefs-synth-info.txt b/Documentation/libtracefs-synth-info.txt
new file mode 100644
index 0000000..6ee0320
--- /dev/null
+++ b/Documentation/libtracefs-synth-info.txt
@@ -0,0 +1,298 @@
+libtracefs(3)
+=============
+
+NAME
+----
+tracefs_synth_echo_cmd, tracefs_synth_get_start_hist, tracefs_synth_get_name,
+tracefs_synth_raw_fmt, tracefs_synth_show_event, tracefs_synth_show_start_hist, tracefs_synth_show_end_hist,
+tracefs_synth_get_event - Retrieve data of synthetic events.
+
+SYNOPSIS
+--------
+[verse]
+--
+*#include <tracefs.h>*
+
+int *tracefs_synth_echo_cmd*(struct trace_seq pass:[*]_seq_, struct tracefs_synth pass:[*]_synth_);
+struct tracefs_hist pass:[*]*tracefs_synth_get_start_hist*(struct tracefs_synth pass:[*]_synth_);
+
+const char pass:[*]*tracefs_synth_get_name*(struct tracefs_synth pass:[*]_synth_);
+int *tracefs_synth_raw_fmt*(struct trace_seq pass:[*]_seq_, struct tracefs_synth pass:[*]_synth_);
+const char pass:[*]*tracefs_synth_show_event*(struct tracefs_synth pass:[*]_synth_);
+const char pass:[*]*tracefs_synth_show_start_hist*(struct tracefs_synth pass:[*]_synth_);
+const char pass:[*]*tracefs_synth_show_end_hist*(struct tracefs_synth pass:[*]_synth_);
+struct tep_event pass:[*]*tracefs_synth_get_event*(struct tep_handle pass:[*]_tep_, struct tracefs_synth pass:[*]_synth_);
+
+--
+
+DESCRIPTION
+-----------
+Synthetic events are dynamic events that are created by matching
+two other events which triggers a synthetic event. One event is the starting
+event which some field is recorded, and when the second event is executed,
+if it has a field (or fields) that matches the starting event's field (or fields)
+then it will trigger the synthetic event. The field values other than the matching
+fields may be passed from the starting event to the end event to perform calculations
+on, or to simply pass as a parameter to the synthetic event.
+
+One common use case is to set "sched_waking" as the starting event. This event is
+triggered when a process is awoken. Then set "sched_switch" as the ending event.
+This event is triggered when a new task is scheduled on the CPU. By setting
+the "common_pid" of both events as the matching fields, the time between the
+two events is considered the wake up latency of that process. Use *TRACEFS_TIMESTAMP*
+as a field for both events to calculate the delta in nanoseconds, or use
+*TRACEFS_TIMESTAMP_USECS* as the compare fields for both events to calculate the
+delta in microseconds. This is used as the example below.
+
+See *tracefs_synth_alloc*(3) for allocation of synthetic events, and
+*tracefs_synth_create*() for creating the synthetic event on the system.
+
+*tracefs_synth_echo_cmd*() acts like *tracefs_synth_create*(), but instead of creating
+the synthetic event in the system, it will write the echo commands to manually create
+it in the _seq_ given.
+
+*tracefs_synth_get_start_hist*() returns a struct tracefs_hist descriptor describing
+the histogram used to create the synthetic event.
+
+[verse]
+--
+enum tracefs_synth_handler {
+ *TRACEFS_SYNTH_HANDLE_MATCH*,
+ *TRACEFS_SYNTH_HANDLE_MAX*,
+ *TRACEFS_SYNTH_HANDLE_CHANGE*,
+};
+--
+
+*tracefs_synth_get_name*() returns the name of the synthetic event or NULL on error.
+The returned string belongs to the synth event object and is freed with the event
+by *tracefs_synth_free*().
+
+*tracefs_synth_raw_fmt*() writes the raw format strings (dynamic event and histograms) of
+the synthetic event in the _seq_ given.
+
+*tracefs_synth_show_event*() returns the format of the dynamic event used by the synthetic
+event or NULL on error. The returned string belongs to the synth event object and is freed
+with the event by *tracefs_synth_free*().
+
+*tracefs_synth_show_start_hist*() returns the format of the start histogram used by the
+synthetic event or NULL on error. The returned string belongs to the synth event object
+and is freed with the event by *tracefs_synth_free*().
+
+*tracefs_synth_show_end_hist*() returns the format of the end histogram used by the
+synthetic event or NULL on error. The returned string belongs to the synth event object
+and is freed with the event by *tracefs_synth_free*().
+
+The *tracefs_synth_get_event*() function returns a tep event, describing the given synthetic
+event. The API detects any newly created or removed dynamic events. The returned pointer to
+tep event is controlled by @tep and must not be freed.
+
+RETURN VALUE
+------------
+*tracefs_synth_get_name*(), *tracefs_synth_show_event*(), *tracefs_synth_show_start_hist*()
+and *tracefs_synth_show_end_hist*() return a string owned by the synth event object.
+
+The *tracefs_synth_get_event*() function returns a pointer to a tep event or NULL in case of an
+error or if the requested synthetic event is missing. The returned pointer to tep event is
+controlled by @tep and must not be freed.
+
+All other functions return zero on success or -1 on error.
+
+ERRORS
+------
+The following errors are for all the above calls:
+
+*EPERM* Not run as root user when required.
+
+*EINVAL* Either a parameter is not valid (NULL when it should not be)
+ or a field that is not compatible for calculations.
+
+*ENODEV* An event or one of its fields is not found.
+
+*EBADE* The fields of the start and end events are not compatible for
+ either matching or comparing.
+
+*ENOMEM* not enough memory is available.
+
+And more errors may have happened from the system calls to the system.
+
+EXAMPLE
+-------
+See *tracefs_sql*(3) for a more indepth use of some of this code.
+
+[source,c]
+--
+#include <stdlib.h>
+#include <tracefs.h>
+
+#define start_event "sched_waking"
+#define start_field "pid"
+
+#define end_event "sched_switch"
+#define end_field "next_pid"
+
+#define match_name "pid"
+
+static struct tracefs_synth *synth;
+
+static void make_event(void)
+{
+ struct tep_handle *tep;
+
+ /* Load all events from the system */
+ tep = tracefs_local_events(NULL);
+
+ /* Initialize the synthetic event */
+ synth = tracefs_synth_alloc(tep, "wakeup_lat",
+ NULL, start_event,
+ NULL, end_event,
+ start_field, end_field,
+ match_name);
+
+ /* The tep is no longer needed */
+ tep_free(tep);
+
+
+ /* Save the "prio" field as "prio" from the start event */
+ tracefs_synth_add_start_field(synth, "prio", NULL);
+
+ /* Save the "next_comm" as "comm" from the end event */
+ tracefs_synth_add_end_field(synth, "next_comm", "comm");
+
+ /* Save the "prev_prio" as "prev_prio" from the end event */
+ tracefs_synth_add_end_field(synth, "prev_prio", NULL);
+
+ /*
+ * Take a microsecond time difference between end and start
+ * and record as "delta"
+ */
+ tracefs_synth_add_compare_field(synth, TRACEFS_TIMESTAMP_USECS,
+ TRACEFS_TIMESTAMP_USECS,
+ TRACEFS_SYNTH_DELTA_END, "delta");
+
+ /* Only record if start event "prio" is less than 100 */
+ tracefs_synth_append_start_filter(synth, TRACEFS_FILTER_COMPARE,
+ "prio", TRACEFS_COMPARE_LT, "100");
+
+ /*
+ * Only record if end event "next_prio" is less than 50
+ * or the previous task's prio was not greater than or equal to 100.
+ * next_prio < 50 || !(prev_prio >= 100)
+ */
+ tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_COMPARE,
+ "next_prio", TRACEFS_COMPARE_LT, "50");
+ tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_OR, NULL, 0, NULL);
+ tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_NOT, NULL, 0, NULL);
+ tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_OPEN_PAREN, NULL, 0, NULL);
+ tracefs_synth_append_end_filter(synth, TRACEFS_FILTER_COMPARE,
+ "prev_prio", TRACEFS_COMPARE_GE, "100");
+ /*
+ * Note, the above only added: "next_prio < 50 || !(prev_prio >= 100"
+ * That's because, when the synth is executed, the remaining close parenthesis
+ * will be added. That is, the string will end up being:
+ * "next_prio < 50 || !(prev_prio >= 100)" when one of tracefs_sync_create()
+ * or tracefs_sync_echo_cmd() is run.
+ */
+}
+
+/* Display how to create the synthetic event */
+static void show_event(void)
+{
+ struct trace_seq s;
+
+ trace_seq_init(&s);
+
+ tracefs_synth_echo_cmd(&s, synth);
+ trace_seq_terminate(&s);
+ trace_seq_do_printf(&s);
+ trace_seq_destroy(&s);
+}
+
+int main (int argc, char **argv)
+{
+ make_event();
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "create")) {
+ /* Create the synthetic event */
+ tracefs_synth_create(synth);
+ } else if (!strcmp(argv[1], "delete")) {
+ /* Delete the synthetic event */
+ tracefs_synth_destroy(synth);
+ } else {
+ printf("usage: %s [create|delete]\n", argv[0]);
+ exit(-1);
+ }
+ } else
+ show_event();
+
+ tracefs_synth_free(synth);
+
+ return 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),
+*tracefs_hist_alloc*(3),
+*tracefs_hist_alloc_2d*(3),
+*tracefs_hist_alloc_nd*(3),
+*tracefs_hist_free*(3),
+*tracefs_hist_add_key*(3),
+*tracefs_hist_add_value*(3),
+*tracefs_hist_add_name*(3),
+*tracefs_hist_start*(3),
+*tracefs_hist_destory*(3),
+*tracefs_hist_add_sort_key*(3),
+*tracefs_hist_sort_key_direction*(3),
+*tracefs_synth_alloc*(3),
+*tracefs_synth_add_match_field*(3),
+*tracefs_synth_add_compare_field*(3),
+*tracefs_synth_add_start_field*(3),
+*tracefs_synth_add_end_field*(3),
+*tracefs_synth_append_start_filter*(3),
+*tracefs_synth_append_end_filter*(3),
+*tracefs_synth_free*(3),
+*tracefs_synth_create*(3),
+*tracefs_synth_destroy*(3),
+*tracefs_synth_complete*(3),
+*tracefs_synth_trace*(3),
+*tracefs_synth_snapshot*(3),
+*tracefs_synth_save*(3),
+
+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).