All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Tom Zanussi <zanussi@kernel.org>
Subject: [for-next][PATCH 08/31] tracing: Add common_comm to histograms
Date: Fri, 09 May 2025 09:12:57 -0400	[thread overview]
Message-ID: <20250509131314.779021770@goodmis.org> (raw)
In-Reply-To: 20250509131249.340302366@goodmis.org

From: Steven Rostedt <rostedt@goodmis.org>

If one wants to trace the name of the task that wakes up a process and
pass that to the synthetic events, there's nothing currently that lets the
synthetic events do that. Add a "common_comm" to the histogram logic that
allows histograms save the current->comm as a variable that can be passed
through and added to a synthetic event:

 # cd /sys/kernel/tracing
 # echo 's:wake_lat char[] waker; char[] wakee; u64 delta;' >> dynamic_events
 # echo 'hist:keys=pid:comm=common_comm:ts=common_timestamp.usecs if !(common_flags & 0x18)' > events/sched/sched_waking/trigger
 # echo 'hist:keys=next_pid:wake_comm=$comm:delta=common_timestamp.usecs-$ts:onmatch(sched.sched_waking).trace(wake_lat,$wake_comm,next_comm,$delta)' > events/sched/sched_switch/trigger

The above will create a synthetic trace event that will save both the name
of the waker and the wakee but only if the wakeup did not happen in a hard
or soft interrupt context.

The "common_comm" is used to save the task->comm at the time of the
initial event and is passed via the "comm" variable to the second event,
and that is saved as the "waker" field in the "wake_lat" synthetic event.

Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://lore.kernel.org/20250407154912.3c6c6246@gandalf.local.home
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 kernel/trace/trace_events_hist.c | 51 ++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index e85bc59c0421..58c9535f61df 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -114,6 +114,7 @@ enum hist_field_fn {
 	HIST_FIELD_FN_BUCKET,
 	HIST_FIELD_FN_TIMESTAMP,
 	HIST_FIELD_FN_CPU,
+	HIST_FIELD_FN_COMM,
 	HIST_FIELD_FN_STRING,
 	HIST_FIELD_FN_DYNSTRING,
 	HIST_FIELD_FN_RELDYNSTRING,
@@ -506,6 +507,7 @@ enum hist_field_flags {
 	HIST_FIELD_FL_CONST		= 1 << 18,
 	HIST_FIELD_FL_PERCENT		= 1 << 19,
 	HIST_FIELD_FL_GRAPH		= 1 << 20,
+	HIST_FIELD_FL_COMM		= 1 << 21,
 };
 
 struct var_defs {
@@ -885,6 +887,15 @@ static u64 hist_field_cpu(struct hist_field *hist_field,
 	return cpu;
 }
 
+static u64 hist_field_comm(struct hist_field *hist_field,
+			  struct tracing_map_elt *elt,
+			  struct trace_buffer *buffer,
+			  struct ring_buffer_event *rbe,
+			  void *event)
+{
+	return (u64)(unsigned long)current->comm;
+}
+
 /**
  * check_field_for_var_ref - Check if a VAR_REF field references a variable
  * @hist_field: The VAR_REF field to check
@@ -1338,6 +1349,8 @@ static const char *hist_field_name(struct hist_field *field,
 		field_name = hist_field_name(field->operands[0], ++level);
 	else if (field->flags & HIST_FIELD_FL_CPU)
 		field_name = "common_cpu";
+	else if (field->flags & HIST_FIELD_FL_COMM)
+		field_name = "common_comm";
 	else if (field->flags & HIST_FIELD_FL_EXPR ||
 		 field->flags & HIST_FIELD_FL_VAR_REF) {
 		if (field->system) {
@@ -2015,6 +2028,13 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
 		goto out;
 	}
 
+	if (flags & HIST_FIELD_FL_COMM) {
+		hist_field->fn_num = HIST_FIELD_FN_COMM;
+		hist_field->size = MAX_FILTER_STR_VAL;
+		hist_field->type = "char[]";
+		goto out;
+	}
+
 	if (WARN_ON_ONCE(!field))
 		goto out;
 
@@ -2359,9 +2379,11 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
 			hist_data->attrs->ts_in_usecs = true;
 	} else if (strcmp(field_name, "common_stacktrace") == 0) {
 		*flags |= HIST_FIELD_FL_STACKTRACE;
-	} else if (strcmp(field_name, "common_cpu") == 0)
+	} else if (strcmp(field_name, "common_cpu") == 0) {
 		*flags |= HIST_FIELD_FL_CPU;
-	else if (strcmp(field_name, "hitcount") == 0)
+	} else if (strcmp(field_name, "common_comm") == 0) {
+		*flags |= HIST_FIELD_FL_COMM | HIST_FIELD_FL_STRING;
+	} else if (strcmp(field_name, "hitcount") == 0)
 		*flags |= HIST_FIELD_FL_HITCOUNT;
 	else {
 		field = trace_find_event_field(file->event_call, field_name);
@@ -2377,6 +2399,8 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
 				*flags |= HIST_FIELD_FL_CPU;
 			} else if (field && field->filter_type == FILTER_STACKTRACE) {
 				*flags |= HIST_FIELD_FL_STACKTRACE;
+			} else if (field && field->filter_type == FILTER_COMM) {
+				*flags |= HIST_FIELD_FL_COMM | HIST_FIELD_FL_STRING;
 			} else {
 				hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
 					 errpos(field_name));
@@ -4327,6 +4351,8 @@ static u64 hist_fn_call(struct hist_field *hist_field,
 		return hist_field_timestamp(hist_field, elt, buffer, rbe, event);
 	case HIST_FIELD_FN_CPU:
 		return hist_field_cpu(hist_field, elt, buffer, rbe, event);
+	case HIST_FIELD_FN_COMM:
+		return hist_field_comm(hist_field, elt, buffer, rbe, event);
 	case HIST_FIELD_FN_STRING:
 		return hist_field_string(hist_field, elt, buffer, rbe, event);
 	case HIST_FIELD_FN_DYNSTRING:
@@ -5212,14 +5238,19 @@ static inline void add_to_key(char *compound_key, void *key,
 	size_t size = key_field->size;
 
 	if (key_field->flags & HIST_FIELD_FL_STRING) {
-		struct ftrace_event_field *field;
 
-		field = key_field->field;
-		if (field->filter_type == FILTER_DYN_STRING ||
-		    field->filter_type == FILTER_RDYN_STRING)
-			size = *(u32 *)(rec + field->offset) >> 16;
-		else if (field->filter_type == FILTER_STATIC_STRING)
-			size = field->size;
+		if (key_field->flags & HIST_FIELD_FL_COMM) {
+			size = strlen((char *)key);
+		} else {
+			struct ftrace_event_field *field;
+
+			field = key_field->field;
+			if (field->filter_type == FILTER_DYN_STRING ||
+			    field->filter_type == FILTER_RDYN_STRING)
+				size = *(u32 *)(rec + field->offset) >> 16;
+			else if (field->filter_type == FILTER_STATIC_STRING)
+				size = field->size;
+		}
 
 		/* ensure NULL-termination */
 		if (size > key_field->size - 1)
@@ -6097,6 +6128,8 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
 
 	if (hist_field->flags & HIST_FIELD_FL_CPU)
 		seq_puts(m, "common_cpu");
+	if (hist_field->flags & HIST_FIELD_FL_COMM)
+		seq_puts(m, "common_comm");
 	else if (hist_field->flags & HIST_FIELD_FL_CONST)
 		seq_printf(m, "%llu", hist_field->constant);
 	else if (field_name) {
-- 
2.47.2



  parent reply	other threads:[~2025-05-09 13:12 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-09 13:12 [for-next][PATCH 00/31] tracing: Updates for v6.16 Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 01/31] tracing: Update function trace addresses with module addresses Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 02/31] tracing: Show function names when possible when listing fields Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 03/31] tracing: Only return an adjusted address if it matches the kernel address Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 04/31] tracing: Adjust addresses for printing out fields Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 05/31] tracing: Show preempt and irq events callsites from the offsets in field print Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 06/31] tracing: Always use memcpy() in histogram add_to_key() Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 07/31] tracing: Move histogram trigger variables from stack to per CPU structure Steven Rostedt
2025-05-09 13:12 ` Steven Rostedt [this message]
2025-05-09 13:12 ` [for-next][PATCH 09/31] ftrace: Show subops in enabled_functions Steven Rostedt
2025-05-09 13:12 ` [for-next][PATCH 10/31] ftrace: Expose call graph depth as unsigned int Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 11/31] ftrace: Comment that ftrace_func_mapper is freed with free_ftrace_hash() Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 12/31] tracing/osnoise: Allow arbitrarily long CPU string Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 13/31] tracing/mmiotrace: Remove reference to unused per CPU data pointer Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 14/31] ftrace: Do not bother checking per CPU "disabled" flag Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 15/31] tracing: Just use this_cpu_read() to access ignore_pid Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 16/31] tracing: Add tracer_tracing_disable/enable() functions Steven Rostedt
2025-05-09 15:49   ` Doug Anderson
2025-05-09 13:13 ` [for-next][PATCH 17/31] tracing: Use tracer_tracing_disable() instead of "disabled" field for ftrace_dump_one() Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 18/31] tracing: kdb: Use tracer_tracing_on/off() instead of setting per CPU disabled Steven Rostedt
2025-05-09 15:49   ` Doug Anderson
2025-05-09 15:57     ` Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 19/31] ftrace: Do not disabled function graph based on "disabled" field Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 20/31] tracing: Do not use per CPU array_buffer.data->disabled for cpumask Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 21/31] ring-buffer: Add ring_buffer_record_is_on_cpu() Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 22/31] tracing: branch: Use trace_tracing_is_on_cpu() instead of "disabled" field Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 23/31] tracing: Convert the per CPU "disabled" counter to local from atomic Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 24/31] tracing: Use atomic_inc_return() for updating "disabled" counter in irqsoff tracer Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 25/31] tracing: Remove unused buffer_page field from trace_array_cpu structure Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 26/31] tracing: Replace deprecated strncpy() with strscpy() for stack_trace_filter_buf Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 27/31] tracing: Rename event_trigger_alloc() to trigger_data_alloc() Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 28/31] tracing: Fix error handling in event_trigger_parse() Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 29/31] tracing: Remove unnecessary "goto out" that simply returns ret is trigger code Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 30/31] tracing: Add a helper function to handle the dereference arg in verifier Steven Rostedt
2025-05-09 13:13 ` [for-next][PATCH 31/31] tracing: Allow the top level trace_marker to write into another instances 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=20250509131314.779021770@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=mhiramat@kernel.org \
    --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 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.