All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] libtracefs: Update hist example
@ 2021-11-23 21:59 Steven Rostedt
  2021-11-23 21:59 ` [PATCH 1/3] libtracefs/sqlhist: Add -B option to use instances for histograms Steven Rostedt
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-11-23 21:59 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

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

Playing with the hist example from the hist man pages, I realized it
should be able to create/show/delet/... user defined events.

Also, updated the sqlhist to take -B as it can create a single
histogram, and that can be done in an instance.

Steven Rostedt (VMware) (3):
  libtracefs/sqlhist: Add -B option to use instances for histograms
  libtracefs/Documentation: Clean up libtracefs-hist man pages
  libtracefs/Documentation: Modify the hist man page example

 Documentation/libtracefs-hist.txt      | 313 +++++++++++++++++++++----
 Documentation/libtracefs-sql.txt       |  28 ++-
 Documentation/libtracefs-sqlhist.txt.1 |   5 +
 3 files changed, 294 insertions(+), 52 deletions(-)

-- 
2.31.1


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

* [PATCH 1/3] libtracefs/sqlhist: Add -B option to use instances for histograms
  2021-11-23 21:59 [PATCH 0/3] libtracefs: Update hist example Steven Rostedt
@ 2021-11-23 21:59 ` Steven Rostedt
  2021-11-23 21:59 ` [PATCH 2/3] libtracefs/Documentation: Clean up libtracefs-hist man pages Steven Rostedt
  2021-11-23 21:59 ` [PATCH 3/3] libtracefs/Documentation: Modify the hist man page example Steven Rostedt
  2 siblings, 0 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-11-23 21:59 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

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

As sqlhist can also create histograms, it should have a way to pass in an
instance value that would be used to create a histogram for a given
instance.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtracefs-sql.txt       | 28 +++++++++++++++++++++-----
 Documentation/libtracefs-sqlhist.txt.1 |  5 +++++
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/Documentation/libtracefs-sql.txt b/Documentation/libtracefs-sql.txt
index 3389090..6297e9a 100644
--- a/Documentation/libtracefs-sql.txt
+++ b/Documentation/libtracefs-sql.txt
@@ -330,7 +330,8 @@ enum action {
 
 #define ACTIONS ((ACTION_MAX - 1))
 
-static int do_sql(const char *buffer, const char *name, const char *var,
+static int do_sql(const char *instance_name,
+		  const char *buffer, const char *name, const char *var,
 		  const char *trace_dir, bool execute, int action,
 		  char **save_fields)
 {
@@ -409,15 +410,28 @@ static int do_sql(const char *buffer, const char *name, const char *var,
 		if (execute)
 			tracefs_synth_create(synth);
 	} else {
+		struct tracefs_instance *instance = NULL;
 		struct tracefs_hist *hist;
+
 		hist = tracefs_synth_get_start_hist(synth);
 		if (!hist) {
 			perror("get_start_hist");
 			exit(-1);
 		}
-		tracefs_hist_echo_cmd(&seq, NULL, hist, 0);
+		if (instance_name) {
+			if (execute)
+				instance = tracefs_instance_create(instance_name);
+			else
+				instance = tracefs_instance_alloc(trace_dir,
+								  instance_name);
+			if (!instance) {
+				perror("Failed to create instance");
+				exit(-1);
+			}
+		}
+		tracefs_hist_echo_cmd(&seq, instance, hist, 0);
 		if (execute)
-			tracefs_hist_start(NULL, hist);
+			tracefs_hist_start(instance, hist);
 	}
 
 	tracefs_synth_free(synth);
@@ -434,6 +448,7 @@ int main (int argc, char **argv)
 	char buf[BUFSIZ];
 	int buffer_size = 0;
 	const char *file = NULL;
+	const char *instance = NULL;
 	bool execute = false;
 	char **save_fields = NULL;
 	const char *name;
@@ -446,7 +461,7 @@ int main (int argc, char **argv)
 	int i;
 
 	for (;;) {
-		c = getopt(argc, argv, "ht:f:en:m:c:sS:T");
+		c = getopt(argc, argv, "ht:f:en:m:c:sS:TB:");
 		if (c == -1)
 			break;
 
@@ -488,6 +503,9 @@ int main (int argc, char **argv)
 		case 'T':
 			action |= ACTION_TRACE | ACTION_SNAPSHOT;
 			break;
+		case 'B':
+			instance = optarg;
+			break;
 		case 'n':
 			name = optarg;
 			break;
@@ -528,7 +546,7 @@ int main (int argc, char **argv)
 		}
 	}
 
-	do_sql(buffer, name, var, trace_dir, execute, action, save_fields);
+	do_sql(instance, buffer, name, var, trace_dir, execute, action, save_fields);
 	free(buffer);
 
 	return 0;
diff --git a/Documentation/libtracefs-sqlhist.txt.1 b/Documentation/libtracefs-sqlhist.txt.1
index 1e94ea4..875b250 100644
--- a/Documentation/libtracefs-sqlhist.txt.1
+++ b/Documentation/libtracefs-sqlhist.txt.1
@@ -88,6 +88,11 @@ OPTIONS
     Save the given fields. The fields must be fields of the "end" event given
     in the *SQL-select-command*
 
+*-B* 'instance'::
+    For simple statements that only produce a histogram, the instance given here
+    will be where the histogram will be created. This is ignored for full synthetic
+    event creation, as sythetic events have a global affect on all tracing instances,
+    where as, histograms only affect a single instance.
 
 EXAMPLES
 --------
-- 
2.31.1


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

* [PATCH 2/3] libtracefs/Documentation: Clean up libtracefs-hist man pages
  2021-11-23 21:59 [PATCH 0/3] libtracefs: Update hist example Steven Rostedt
  2021-11-23 21:59 ` [PATCH 1/3] libtracefs/sqlhist: Add -B option to use instances for histograms Steven Rostedt
@ 2021-11-23 21:59 ` Steven Rostedt
  2021-11-23 21:59 ` [PATCH 3/3] libtracefs/Documentation: Modify the hist man page example Steven Rostedt
  2 siblings, 0 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-11-23 21:59 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

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

Include the tracefs_hist_key_type enum and the structure of
tracefs_hist_axis in the man page as that is expected to be useful. It
should not be expected that people must read the actual header for this
information.

Also add spaces between some of the functions to separate out
functionality a little to make it easier to read.

Also fix the missing "pass:" before "[*]axes".

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtracefs-hist.txt | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/Documentation/libtracefs-hist.txt b/Documentation/libtracefs-hist.txt
index 31ea712..ab802cf 100644
--- a/Documentation/libtracefs-hist.txt
+++ b/Documentation/libtracefs-hist.txt
@@ -12,6 +12,23 @@ SYNOPSIS
 --
 *#include <tracefs.h>*
 
+enum tracefs_hist_key_type {
+	TRACEFS_HIST_KEY_NORMAL = 0,
+	TRACEFS_HIST_KEY_HEX,
+	TRACEFS_HIST_KEY_SYM,
+	TRACEFS_HIST_KEY_SYM_OFFSET,
+	TRACEFS_HIST_KEY_SYSCALL,
+	TRACEFS_HIST_KEY_EXECNAME,
+	TRACEFS_HIST_KEY_LOG,
+	TRACEFS_HIST_KEY_USECS,
+	TRACEFS_HIST_KEY_MAX
+};
+
+struct tracefs_hist_axis {
+	const char *key;
+	enum tracefs_hist_key_type type;
+};
+
 struct tracefs_hist pass:[*]tracefs_hist1d_alloc(struct tracefs_tep pass:[*] tep,
 			const char pass:[*]system, const char pass:[*]event,
 			const char pass:[*]key, enum tracefs_hist_key_type type);
@@ -21,27 +38,33 @@ struct tracefs_hist pass:[*]tracefs_hist2d_alloc(struct tracefs_tep pass:[*] tep
 			const char pass:[*]key2, enum tracefs_hist_key_type type2));
 struct tracefs_hist pass:[*]tracefs_hist_alloc(struct tracefs_tep pass:[*] tep,
 			const char pass:[*]system, const char pass:[*]event,
-			struct tracefs_hist_axis [*]axes);
+			struct tracefs_hist_axis pass:[*]axes);
 void tracefs_hist_free(struct tracefs_hist pass:[*]hist);
+
 int tracefs_hist_add_key(struct tracefs_hist pass:[*]hist, const char pass:[*]key,
 			 enum tracefs_hist_key_type type);
 int tracefs_hist_add_value(struct tracefs_hist pass:[*]hist, const char pass:[*]value);
 int tracefs_hist_add_sort_key(struct tracefs_hist pass:[*]hist,
 			      const char pass:[*]sort_key);
+
 int tracefs_hist_set_sort_key(struct tracefs_hist pass:[*]hist,
 			      const char pass:[*]sort_key, ...);
 int tracefs_hist_sort_key_direction(struct tracefs_hist pass:[*]hist,
 				    const char pass:[*]sort_key,
 				    enum tracefs_hist_sort_direction dir);
+
 int tracefs_hist_add_name(struct tracefs_hist pass:[*]hist, const char pass:[*]name);
+
 int tracefs_hist_append_filter(struct tracefs_hist pass:[*]hist,
 			       enum tracefs_filter type,
 			       const char pass:[*]field,
 			       enum tracefs_compare compare,
 			       const char pass:[*]val);
+
 int tracefs_hist_echo_cmd(struct trace_seq pass:[*]s, struct tracefs_instance pass:[*]instance,
 			  struct tracefs_hist pass:[*]hist,
 			  enum tracefs_hist_command command);
+
 int tracefs_hist_command(struct tracefs_instance pass:[*]instance,
 			 struct tracefs_hist pass:[*]hist,
 			 enum tracefs_hist_command command);
-- 
2.31.1


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

* [PATCH 3/3] libtracefs/Documentation: Modify the hist man page example
  2021-11-23 21:59 [PATCH 0/3] libtracefs: Update hist example Steven Rostedt
  2021-11-23 21:59 ` [PATCH 1/3] libtracefs/sqlhist: Add -B option to use instances for histograms Steven Rostedt
  2021-11-23 21:59 ` [PATCH 2/3] libtracefs/Documentation: Clean up libtracefs-hist man pages Steven Rostedt
@ 2021-11-23 21:59 ` Steven Rostedt
  2 siblings, 0 replies; 4+ messages in thread
From: Steven Rostedt @ 2021-11-23 21:59 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

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

Update the hist man page example to allow modification of a user defined
histogram type.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtracefs-hist.txt | 288 +++++++++++++++++++++++++-----
 1 file changed, 242 insertions(+), 46 deletions(-)

diff --git a/Documentation/libtracefs-hist.txt b/Documentation/libtracefs-hist.txt
index ab802cf..c501d5a 100644
--- a/Documentation/libtracefs-hist.txt
+++ b/Documentation/libtracefs-hist.txt
@@ -245,6 +245,7 @@ EXAMPLE
 [source,c]
 --
 #include <stdlib.h>
+#include <unistd.h>
 #include <tracefs.h>
 
 enum commands {
@@ -256,63 +257,184 @@ enum commands {
 	SHOW,
 };
 
-int main (int argc, char **argv, char **env)
+static void parse_system_event(char *group, char **system, char **event)
+{
+	*system = strtok(group, "/");
+	*event = strtok(NULL, "/");
+	if (!*event) {
+		*event = *system;
+		*system = NULL;
+	}
+}
+
+static int parse_keys(char *keys, struct tracefs_hist_axis **axes)
+{
+	char *sav = NULL;
+	char *key;
+	int cnt = 0;
+
+	for (key = strtok_r(keys, ",", &sav); key; key = strtok_r(NULL, ",", &sav)) {
+		struct tracefs_hist_axis *ax;
+		char *att;
+
+		ax = realloc(*axes, sizeof(*ax) * (cnt + 2));
+		if (!ax) {
+			perror("Failed to allocate axes");
+			exit(-1);
+		}
+		ax[cnt].key = key;
+		ax[cnt].type = 0;
+		ax[cnt + 1].key = NULL;
+		ax[cnt + 1].type = 0;
+
+		*axes = ax;
+
+		att = strchr(key, '.');
+		if (att) {
+			*att++ = '\0';
+			if (strcmp(att, "hex") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_HEX;
+			else if (strcmp(att, "sym") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_SYM;
+			else if (strcmp(att, "sym_offset") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_SYM_OFFSET;
+			else if (strcmp(att, "syscall") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_SYSCALL;
+			else if (strcmp(att, "exec") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_EXECNAME;
+			else if (strcmp(att, "log") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_LOG;
+			else if (strcmp(att, "usecs") == 0)
+				ax[cnt].type = TRACEFS_HIST_KEY_USECS;
+			else {
+				fprintf(stderr, "Undefined attribute '%s'\n", att);
+				fprintf(stderr,"  Acceptable attributes:\n");
+				fprintf(stderr,"    hex, sym, sym_offset, syscall, exe, log, usecs\n");
+				exit(-1);
+			}
+		}
+		cnt++;
+	}
+	return cnt;
+}
+
+static void process_hist(enum commands cmd, const char *instance_name,
+			 char *group, char *keys, char *vals, char *sort,
+			 char *ascend, char *desc)
 {
-	struct tracefs_instance *instance;
+	struct tracefs_instance *instance = NULL;
 	struct tracefs_hist *hist;
 	struct tep_handle *tep;
-	enum commands cmd;
-	char *cmd_str;
+	struct tracefs_hist_axis *axes = NULL;
+	char *system;
+	char *event;
+	char *sav;
+	char *val;
 	int ret;
+	int cnt;
 
-	if (argc < 2) {
-		fprintf(stderr, "usage: %s command\n", argv[0]);
+	if (instance_name) {
+		instance = tracefs_instance_create(instance_name);
+		if (!instance) {
+			fprintf(stderr, "Failed instance create\n");
+			exit(-1);
+		}
+	}
+
+	tep = tracefs_local_events(NULL);
+	if (!tep) {
+		perror("Could not read events");
 		exit(-1);
 	}
 
-	cmd_str = argv[1];
+	parse_system_event(group, &system, &event);
 
-	if (!strcmp(cmd_str, "start"))
-		cmd = START;
-	else if (!strcmp(cmd_str, "pause"))
-		cmd = PAUSE;
-	else if (!strcmp(cmd_str, "cont"))
-		cmd = CONT;
-	else if (!strcmp(cmd_str, "reset"))
-		cmd = RESET;
-	else if (!strcmp(cmd_str, "delete"))
-		cmd = DELETE;
-	else if (!strcmp(cmd_str, "show"))
-		cmd = SHOW;
-	else {
-		fprintf(stderr, "Unknown command %s\n", cmd_str);
+	if (cmd == SHOW) {
+		char *content;
+		content = tracefs_event_file_read(instance, system, event,
+						  "hist", NULL);
+		if (!content) {
+			perror("Reading hist file");
+			exit(-1);
+		}
+		printf("%s\n", content);
+		free(content);
+		return;
+	}
+
+	if (!keys) {
+		fprintf(stderr, "Command needs -k option\n");
 		exit(-1);
 	}
 
-	instance = tracefs_instance_create("hist_test");
-	if (!instance) {
-		fprintf(stderr, "Failed instance create\n");
+	cnt = parse_keys(keys, &axes);
+	if (!cnt) {
+		fprintf(stderr, "No keys??\n");
 		exit(-1);
 	}
 
-	tep = tracefs_local_events(NULL);
-	hist = tracefs_hist2d_alloc(tep, "kmem", "kmalloc",
-				    "call_site", TRACEFS_HIST_KEY_SYM,
-				    "bytes_req", 0);
+	/* Show examples of hist1d and hist2d */
+	switch (cnt) {
+	case 1:
+		hist = tracefs_hist1d_alloc(tep, system, event,
+					    axes[0].key, axes[0].type);
+		break;
+	case 2:
+		hist = tracefs_hist2d_alloc(tep, system, event,
+					    axes[0].key, axes[0].type,
+					    axes[1].key, axes[1].type);
+		break;
+	default:
+		/* Really, 1 and 2 could use this too */
+		hist = tracefs_hist_alloc(tep, system, event, axes);
+	}
 	if (!hist) {
 		fprintf(stderr, "Failed hist create\n");
 		exit(-1);
 	}
 
-	ret = tracefs_hist_add_value(hist, "bytes_alloc");
-	ret |= tracefs_hist_add_sort_key(hist, "bytes_req");
-	ret |= tracefs_hist_add_sort_key(hist, "bytes_alloc");
+	if (vals) {
+		sav = NULL;
+		for (val = strtok_r(vals, ",", &sav); val; val = strtok_r(NULL, ",", &sav)) {
+			ret = tracefs_hist_add_value(hist, val);
+			if (ret) {
+				fprintf(stderr, "Failed to add value %s\n", val);
+				exit(-1);
+			}
+		}
+	}
 
-	ret |= tracefs_hist_sort_key_direction(hist, "bytes_alloc",
-					       TRACEFS_HIST_SORT_DESCENDING);
-	if (ret) {
-		fprintf(stderr, "Failed modifying histogram\n");
-		exit(-1);
+	if (sort) {
+		sav = NULL;
+		for (val = strtok_r(sort, ",", &sav); val; val = strtok_r(NULL, ",", &sav)) {
+			ret = tracefs_hist_add_sort_key(hist, val);
+			if (ret) {
+				fprintf(stderr, "Failed to add sort key/val %s\n", val);
+				exit(-1);
+			}
+		}
+	}
+
+	if (ascend) {
+		sav = NULL;
+		for (val = strtok_r(ascend, ",", &sav); val; val = strtok_r(NULL, ",", &sav)) {
+			ret = tracefs_hist_sort_key_direction(hist, val, TRACEFS_HIST_SORT_ASCENDING);
+			if (ret) {
+				fprintf(stderr, "Failed to add ascending key/val %s\n", val);
+				exit(-1);
+			}
+		}
+	}
+
+	if (desc) {
+		sav = NULL;
+		for (val = strtok_r(desc, ",", &sav); val; val = strtok_r(NULL, ",", &sav)) {
+			ret = tracefs_hist_sort_key_direction(hist, val, TRACEFS_HIST_SORT_DESCENDING);
+			if (ret) {
+				fprintf(stderr, "Failed to add descending key/val %s\n", val);
+				exit(-1);
+			}
+		}
 	}
 
 	tracefs_error_clear(instance);
@@ -338,22 +460,96 @@ int main (int argc, char **argv, char **env)
 	case DELETE:
 		ret = tracefs_hist_destroy(instance, hist);
 		break;
-	case SHOW: {
-		char *content;
-		content = tracefs_event_file_read(instance, "kmem", "kmalloc",
-						  "hist", NULL);
-		ret = content ? 0 : -1;
-		if (content) {
-			printf("%s\n", content);
-			free(content);
-		}
+	case SHOW:
+		/* Show was already done */
 		break;
 	}
-	}
 	if (ret)
 		fprintf(stderr, "Failed: command\n");
 	exit(ret);
 }
+
+int main (int argc, char **argv, char **env)
+{
+	enum commands cmd;
+	char *instance = NULL;
+	char *cmd_str;
+	char *event = NULL;
+	char *keys = NULL;
+	char *vals = NULL;
+	char *sort = NULL;
+	char *desc = NULL;
+	char *ascend = NULL;
+
+	if (argc < 2) {
+		fprintf(stderr, "usage: %s command [-B instance][-e [system/]event][-k keys][-v vals][-s sort]\n", argv[0]);
+		fprintf(stderr, "      [-a ascending][-d descending]\n");
+		exit(-1);
+	}
+
+	cmd_str = argv[1];
+
+	if (!strcmp(cmd_str, "start"))
+		cmd = START;
+	else if (!strcmp(cmd_str, "pause"))
+		cmd = PAUSE;
+	else if (!strcmp(cmd_str, "cont"))
+		cmd = CONT;
+	else if (!strcmp(cmd_str, "reset"))
+		cmd = RESET;
+	else if (!strcmp(cmd_str, "delete"))
+		cmd = DELETE;
+	else if (!strcmp(cmd_str, "show"))
+		cmd = SHOW;
+	else {
+		fprintf(stderr, "Unknown command %s\n", cmd_str);
+		exit(-1);
+	}
+
+	for (;;) {
+		int c;
+
+		c = getopt(argc - 1, argv + 1, "e:k:v:B:s:d:a:");
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'e':
+			event = optarg;
+			break;
+		case 'k':
+			keys = optarg;
+			break;
+		case 'v':
+			vals = optarg;
+			break;
+		case 'B':
+			instance = optarg;
+			break;
+		case 's':
+			sort = optarg;
+			break;
+		case 'd':
+			desc = optarg;
+			break;
+		case 'a':
+			ascend = optarg;
+			break;
+		}
+	}
+	if (!event) {
+		event = "kmem/kmalloc";
+		if (!keys)
+			keys = "call_site.sym,bytes_req";
+		if (!vals)
+			vals = "bytes_alloc";
+		if (!sort)
+			sort = "bytes_req,bytes_alloc";
+		if (!desc)
+			desc = "bytes_alloc";
+	}
+	process_hist(cmd, instance, event, keys, vals, sort, ascend, desc);
+}
 --
 
 FILES
-- 
2.31.1


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

end of thread, other threads:[~2021-11-23 22:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-23 21:59 [PATCH 0/3] libtracefs: Update hist example Steven Rostedt
2021-11-23 21:59 ` [PATCH 1/3] libtracefs/sqlhist: Add -B option to use instances for histograms Steven Rostedt
2021-11-23 21:59 ` [PATCH 2/3] libtracefs/Documentation: Clean up libtracefs-hist man pages Steven Rostedt
2021-11-23 21:59 ` [PATCH 3/3] libtracefs/Documentation: Modify the hist man page example Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.