linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-trace-devel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Tom Zanussi <zanussi@kernel.org>,
	Daniel Bristot de Oliveira <bristot@redhat.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	linux-rt-users <linux-rt-users@vger.kernel.org>,
	Clark Williams <williams@redhat.com>,
	"Steven Rostedt (VMware)" <rostedt@goodmis.org>
Subject: [PATCH v2 21/21] libtracefs: Add CAST(x AS _COUNTER_) syntax to create values in histograms
Date: Tue,  3 Aug 2021 00:23:47 -0400	[thread overview]
Message-ID: <20210803042347.679499-22-rostedt@goodmis.org> (raw)
In-Reply-To: <20210803042347.679499-1-rostedt@goodmis.org>

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

Use the CAST() command of SQL to define which items in the select should
be cast as values and not keys. By casting the field as the special value
_COUNTER_, it will turn the selection item into a value.

For example:

   SELECT common_pid, CAST(bytes_req AS _COUNTER_) FROM kmalloc

Will create:

  echo 'hist:keys=common_pid:vals=bytes_req' > events/kmem/kmalloc/trigger

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtracefs-sql.txt | 24 ++++++++++++++++++++++++
 include/tracefs-local.h          |  2 ++
 include/tracefs.h                |  3 +++
 src/tracefs-hist.c               | 28 ++++++++++++++++++++++++++--
 src/tracefs-sqlhist.c            | 23 +++++++++++++++++++++++
 5 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/Documentation/libtracefs-sql.txt b/Documentation/libtracefs-sql.txt
index 314f607fa84e..7b616fa27d23 100644
--- a/Documentation/libtracefs-sql.txt
+++ b/Documentation/libtracefs-sql.txt
@@ -238,6 +238,30 @@ name of the process.
 
 *LOG* or *LOG2* - bucket the key values in a log 2 values (1, 2, 3-4, 5-8, 9-16, 17-32, ...)
 
+The above fields are not case sensitive, and "LOG2" works as good as "log".
+
+A special CAST to _COUNTER_ or __COUNTER__ will make the field a value and not
+a key. For example:
+
+[source,c]
+--
+  SELECT common_pid, CAST(bytes_req AS _COUNTER_) FROM kmalloc
+--
+
+Which will create
+
+[source,c]
+--
+  echo 'hist:keys=common_pid:vals=bytes_req' > events/kmem/kmalloc/trigger
+
+  cat events/kmem/kmalloc/hist
+
+{ common_pid:       1812 } hitcount:          1  bytes_req:         32
+{ common_pid:       9111 } hitcount:          2  bytes_req:        272
+{ common_pid:       1768 } hitcount:          3  bytes_req:       1112
+{ common_pid:          0 } hitcount:          4  bytes_req:        512
+{ common_pid:      18297 } hitcount:         11  bytes_req:       2004
+--
 
 RETURN VALUE
 ------------
diff --git a/include/tracefs-local.h b/include/tracefs-local.h
index 07d40b2fae4f..684eccffafee 100644
--- a/include/tracefs-local.h
+++ b/include/tracefs-local.h
@@ -88,6 +88,8 @@ int trace_append_filter(char **filter, unsigned int *state,
 struct tracefs_synth *synth_init_from(struct tep_handle *tep,
 				      const char *start_system,
 				      const char *start_event);
+
+#define HIST_COUNTER_TYPE	(TRACEFS_HIST_KEY_MAX + 100)
 int synth_add_start_field(struct tracefs_synth *synth,
 			  const char *start_field,
 			  const char *name,
diff --git a/include/tracefs.h b/include/tracefs.h
index 219adba4b0ce..17020de0108a 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -264,6 +264,7 @@ enum tracefs_hist_key_type {
 	TRACEFS_HIST_KEY_EXECNAME,
 	TRACEFS_HIST_KEY_LOG,
 	TRACEFS_HIST_KEY_USECS,
+	TRACEFS_HIST_KEY_MAX
 };
 
 enum tracefs_hist_sort_direction {
@@ -275,6 +276,8 @@ enum tracefs_hist_sort_direction {
 #define TRACEFS_HIST_TIMESTAMP_USECS	"common_timestamp.usecs"
 #define TRACEFS_HIST_CPU		"cpu"
 
+#define TRACEFS_HIST_COUNTER		"__COUNTER__"
+
 #define TRACEFS_HIST_HITCOUNT		"hitcount"
 
 struct tracefs_hist;
diff --git a/src/tracefs-hist.c b/src/tracefs-hist.c
index d62422399552..c3aecf9a8fef 100644
--- a/src/tracefs-hist.c
+++ b/src/tracefs-hist.c
@@ -256,7 +256,7 @@ int tracefs_hist_add_key(struct tracefs_hist *hist, const char *key,
 	bool use_key = false;
 	char *key_type = NULL;
 	char **new_list;
-	int ret;
+	int ret = -1;
 
 	switch (type) {
 	case TRACEFS_HIST_KEY_NORMAL:
@@ -284,6 +284,9 @@ int tracefs_hist_add_key(struct tracefs_hist *hist, const char *key,
 	case TRACEFS_HIST_KEY_USECS:
 		ret = asprintf(&key_type, "%s.usecs", key);
 		break;
+	case TRACEFS_HIST_KEY_MAX:
+		/* error */
+		break;
 	}
 
 	if (ret < 0)
@@ -1450,6 +1453,9 @@ tracefs_synth_get_start_hist(struct tracefs_synth *synth)
 	for (i = 0; keys[i]; i++) {
 		int type = types ? types[i] : 0;
 
+		if (type == HIST_COUNTER_TYPE)
+			continue;
+
 		key = keys[i];
 
 		if (i) {
@@ -1466,7 +1472,25 @@ tracefs_synth_get_start_hist(struct tracefs_synth *synth)
 		}
 	}
 
-	if (hist && synth->start_filter) {
+	if (!hist)
+		return NULL;
+
+	for (i = 0; keys[i]; i++) {
+		int type = types ? types[i] : 0;
+
+		if (type != HIST_COUNTER_TYPE)
+			continue;
+
+		key = keys[i];
+
+		ret = tracefs_hist_add_value(hist, key);
+		if (ret < 0) {
+			tracefs_hist_free(hist);
+			return NULL;
+		}
+	}
+
+	if (synth->start_filter) {
 		hist->filter = strdup(synth->start_filter);
 		if (!hist->filter) {
 			tracefs_hist_free(hist);
diff --git a/src/tracefs-sqlhist.c b/src/tracefs-sqlhist.c
index 88563e98f298..1a3cf37c84ba 100644
--- a/src/tracefs-sqlhist.c
+++ b/src/tracefs-sqlhist.c
@@ -1253,6 +1253,17 @@ static int verify_field_type(struct tep_handle *tep,
 	if (!type)
 		return -1;
 
+	if (!strcmp(type, TRACEFS_HIST_COUNTER) ||
+	    !strcmp(type, "_COUNTER_")) {
+		ret = HIST_COUNTER_TYPE;
+		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY)) {
+			parse_error(sb, field->raw,
+				    "'%s' is a string, and counters may only be used with numbers\n");
+			ret = -1;
+		}
+		goto out;
+	}
+
 	for (i = 0; type[i]; i++)
 		type[i] = tolower(type[i]);
 
@@ -1292,6 +1303,7 @@ static int verify_field_type(struct tep_handle *tep,
 			    field->raw, type);
 		ret = -1;
 	}
+ out:
 	free(type);
 	return ret;
  fail_type:
@@ -1319,6 +1331,7 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep,
 	const char *end_match;
 	bool started_start = false;
 	bool started_end = false;
+	bool non_val = false;
 	int ret;
 
 	if (!table->from)
@@ -1396,6 +1409,8 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep,
 				type = verify_field_type(tep, table->sb, expr);
 				if (type < 0)
 					goto free;
+				if (type != HIST_COUNTER_TYPE)
+					non_val = true;
 				ret = synth_add_start_field(synth,
 						field->field, field->label,
 						type);
@@ -1426,6 +1441,14 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep,
 		}
 	}
 
+	if (!non_val && !table->to) {
+		table->sb->line_no = 0;
+		table->sb->line_idx = 10;
+		parse_error(table->sb, "CAST",
+			    "Not all SELECT items can be of type _COUNTER_\n");
+		goto free;
+	}
+
 	for (expr = table->where; expr; expr = expr->next) {
 		const char *filter_system = NULL;
 		const char *filter_event = NULL;
-- 
2.30.2


  parent reply	other threads:[~2021-08-03  4:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-03  4:23 [PATCH v2 00/21] libtracefs: Introducing tracefs_sql() to create synthetice events with an SQL line Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 01/21] libtracefs: Added new API tracefs_sql() Steven Rostedt
2021-08-03  7:27   ` Lukas Bulwahn
2021-08-03  4:23 ` [PATCH v2 02/21] tracefs: Add unit tests for tracefs_sql() Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 03/21] libtracefs: Add comparing start and end fields in tracefs_sql() Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 04/21] libtracefs: Add unit test to test tracefs_sql() compare Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 05/21] libtracefs: Add filtering for start and end events in tracefs_sql() Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 06/21] libtracefs: Add unit test to test tracefs_sql() where clause Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 07/21] libtracefs: Make sqlhist parser reentrant Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 08/21] libtracefs: Make parser unique to libtracefs Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 09/21] libtracefs: Add line number and index to expr structure Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 10/21] libtracefs: Add error message when match fields are not FROM and JOIN events Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 11/21] libtracefs: Add error message when match or init fails from bad events Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 12/21] libtracefs; Add error message for bad selections to SQL sequence Steven Rostedt
2021-08-03 12:40   ` Daniel Bristot de Oliveira
2021-08-03  4:23 ` [PATCH v2 13/21] libtracefs: Add error message when compare fields fail Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 14/21] libtracefs: Add error message for grouping events in SQL filter Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 15/21] libtracefs: Add error message for bad filters in SQL statement Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 16/21] libtracefs: Add error message when calculation has no label Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 17/21] libtracefs: Add man page for tracefs_sql() Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 18/21] libtracefs: Allow for simple SQL statements to create a histogram Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 19/21] libtracefs: Allow trace_sql() to take keywords for fields with backslash Steven Rostedt
2021-08-03  4:23 ` [PATCH v2 20/21] libtracefs: Add CAST() syntax to SQL parsing for histogram types Steven Rostedt
2021-08-03  4:23 ` Steven Rostedt [this message]
2021-08-04 11:57 ` [PATCH v2 00/21] libtracefs: Introducing tracefs_sql() to create synthetice events with an SQL line Ahmed S. Darwish
2021-08-04 13:23   ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210803042347.679499-22-rostedt@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=bristot@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=williams@redhat.com \
    --cc=zanussi@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).