Commit 31eb415b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ftrace updates from Steven Rostedt:

 - Record function parameters for function and function graph tracers

   An option has been added to function tracer (func-args) and the
   function graph tracer (funcgraph-args) that when set, the tracers
   will record the registers that hold the arguments into each function
   event. On reading of the trace, it will use BTF to print those
   arguments. Most archs support up to 6 arguments (depending on the
   complexity of the arguments) and those are printed.

   If a function has more arguments then what was recorded, the output
   will end with " ... )".

   Example of function graph tracer:

	6)              | dummy_xmit [dummy](skb = 0x8887c100, dev = 0x872ca000) {
	6)              |   consume_skb(skb = 0x8887c100) {
	6)              |     skb_release_head_state(skb = 0x8887c100) {
	6)  0.178 us    |       sock_wfree(skb = 0x8887c100)
	6)  0.627 us    |     }

 - The rest of the changes are minor clean ups and fixes

* tag 'ftrace-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: Use hashtable.h for event_hash
  tracing: Fix use-after-free in print_graph_function_flags during tracer switching
  function_graph: Remove the unused variable func
  ftrace: Add arguments to function tracer
  ftrace: Have funcgraph-args take affect during tracing
  ftrace: Add support for function argument to graph tracer
  ftrace: Add print_function_args()
  ftrace: Have ftrace_free_filter() WARN and exit if ops is active
  fgraph: Correct typo in ftrace_return_to_handler comment
parents dd161f74 391dda1b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -35,4 +35,9 @@ struct ftrace_regs;

#endif /* HAVE_ARCH_FTRACE_REGS */

/* This can be overridden by the architectures */
#ifndef FTRACE_REGS_MAX_ARGS
# define FTRACE_REGS_MAX_ARGS	6
#endif

#endif /* _LINUX_FTRACE_REGS_H */
+12 −0
Original line number Diff line number Diff line
@@ -263,6 +263,18 @@ config FUNCTION_GRAPH_RETADDR
	  the function is called. This feature is off by default, and you can
	  enable it via the trace option funcgraph-retaddr.

config FUNCTION_TRACE_ARGS
       bool
	depends on HAVE_FUNCTION_ARG_ACCESS_API
	depends on DEBUG_INFO_BTF
	default y
	help
	  If supported with function argument access API and BTF, then
	  the function tracer and function graph tracer will support printing
	  of function arguments. This feature is off by default, and can be
	  enabled via the trace option func-args (for the function tracer) and
	  funcgraph-args (for the function graph tracer)

config DYNAMIC_FTRACE
	bool "enable/disable function tracing dynamically"
	depends on FUNCTION_TRACER
+1 −1
Original line number Diff line number Diff line
@@ -865,7 +865,7 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointe
}

/*
 * After all architecures have selected HAVE_FUNCTION_GRAPH_FREGS, we can
 * After all architectures have selected HAVE_FUNCTION_GRAPH_FREGS, we can
 * leave only ftrace_return_to_handler(fregs).
 */
#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FREGS
+2 −0
Original line number Diff line number Diff line
@@ -1293,6 +1293,8 @@ static void free_ftrace_hash_rcu(struct ftrace_hash *hash)
void ftrace_free_filter(struct ftrace_ops *ops)
{
	ftrace_ops_init(ops);
	if (WARN_ON(ops->flags & FTRACE_OPS_FL_ENABLED))
		return;
	free_ftrace_hash(ops->func_hash->filter_hash);
	free_ftrace_hash(ops->func_hash->notrace_hash);
}
+12 −2
Original line number Diff line number Diff line
@@ -2878,13 +2878,16 @@ trace_buffer_unlock_commit_nostack(struct trace_buffer *buffer,

void
trace_function(struct trace_array *tr, unsigned long ip, unsigned long
	       parent_ip, unsigned int trace_ctx)
	       parent_ip, unsigned int trace_ctx, struct ftrace_regs *fregs)
{
	struct trace_buffer *buffer = tr->array_buffer.buffer;
	struct ring_buffer_event *event;
	struct ftrace_entry *entry;
	int size = sizeof(*entry);

	event = __trace_buffer_lock_reserve(buffer, TRACE_FN, sizeof(*entry),
	size += FTRACE_REGS_MAX_ARGS * !!fregs * sizeof(long);

	event = __trace_buffer_lock_reserve(buffer, TRACE_FN, size,
					    trace_ctx);
	if (!event)
		return;
@@ -2892,6 +2895,13 @@ trace_function(struct trace_array *tr, unsigned long ip, unsigned long
	entry->ip			= ip;
	entry->parent_ip		= parent_ip;

#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
	if (fregs) {
		for (int i = 0; i < FTRACE_REGS_MAX_ARGS; i++)
			entry->args[i] = ftrace_regs_get_argument(fregs, i);
	}
#endif

	if (static_branch_unlikely(&trace_function_exports_enabled))
		ftrace_exports(event, TRACE_EXPORT_FUNCTION);
	__buffer_unlock_commit(buffer, event);
Loading