Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf: ftrace: add graph tracer options args/retval/retval-hex/retaddr

This change adds support for new funcgraph tracer options funcgraph-args,
funcgraph-retval, funcgraph-retval-hex and funcgraph-retaddr.

The new added options are:
- args : Show function arguments.
- retval : Show function return value.
- retval-hex : Show function return value in hexadecimal format.
- retaddr : Show function return address.

# ./perf ftrace -G vfs_write --graph-opts retval,retaddr
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
5) | mutex_unlock() { /* <-rb_simple_write+0xda/0x150 */
5) 0.188 us | local_clock(); /* <-lock_release+0x2ad/0x440 ret=0x3bf2a3cf90e */
5) | rt_mutex_slowunlock() { /* <-rb_simple_write+0xda/0x150 */
5) | _raw_spin_lock_irqsave() { /* <-rt_mutex_slowunlock+0x4f/0x200 */
5) 0.123 us | preempt_count_add(); /* <-_raw_spin_lock_irqsave+0x23/0x90 ret=0x0 */
5) 0.128 us | local_clock(); /* <-__lock_acquire.isra.0+0x17a/0x740 ret=0x3bf2a3cfc8b */
5) 0.086 us | do_raw_spin_trylock(); /* <-_raw_spin_lock_irqsave+0x4a/0x90 ret=0x1 */
5) 0.845 us | } /* _raw_spin_lock_irqsave ret=0x292 */
5) | _raw_spin_unlock_irqrestore() { /* <-rt_mutex_slowunlock+0x191/0x200 */
5) 0.097 us | local_clock(); /* <-lock_release+0x2ad/0x440 ret=0x3bf2a3cff1f */
5) 0.086 us | do_raw_spin_unlock(); /* <-_raw_spin_unlock_irqrestore+0x23/0x60 ret=0x1 */
5) 0.104 us | preempt_count_sub(); /* <-_raw_spin_unlock_irqrestore+0x35/0x60 ret=0x0 */
5) 0.726 us | } /* _raw_spin_unlock_irqrestore ret=0x80000000 */
5) 1.881 us | } /* rt_mutex_slowunlock ret=0x0 */
5) 2.931 us | } /* mutex_unlock ret=0x0 */

Signed-off-by: Changbin Du <changbin.du@huawei.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250613114048.132336-1-changbin.du@huawei.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Changbin Du and committed by
Namhyung Kim
129f70bd e9fdf0d2

+67 -1
+4
tools/perf/Documentation/perf-ftrace.txt
··· 123 123 --graph-opts:: 124 124 List of options allowed to set: 125 125 126 + - args - Show function arguments. 127 + - retval - Show function return value. 128 + - retval-hex - Show function return value in hexadecimal format. 129 + - retaddr - Show function return address. 126 130 - nosleep-time - Measure on-CPU time only for function_graph tracer. 127 131 - noirqs - Ignore functions that happen inside interrupt. 128 132 - verbose - Show process names, PIDs, timestamps, etc.
+59 -1
tools/perf/builtin-ftrace.c
··· 301 301 write_tracing_option_file("funcgraph-proc", "0"); 302 302 write_tracing_option_file("funcgraph-abstime", "0"); 303 303 write_tracing_option_file("funcgraph-tail", "0"); 304 + write_tracing_option_file("funcgraph-args", "0"); 305 + write_tracing_option_file("funcgraph-retval", "0"); 306 + write_tracing_option_file("funcgraph-retval-hex", "0"); 307 + write_tracing_option_file("funcgraph-retaddr", "0"); 304 308 write_tracing_option_file("latency-format", "0"); 305 309 write_tracing_option_file("irq-info", "0"); 306 310 } ··· 546 542 return 0; 547 543 } 548 544 545 + static int set_tracing_funcgraph_args(struct perf_ftrace *ftrace) 546 + { 547 + if (ftrace->graph_args) { 548 + if (write_tracing_option_file("funcgraph-args", "1") < 0) 549 + return -1; 550 + } 551 + 552 + return 0; 553 + } 554 + 555 + static int set_tracing_funcgraph_retval(struct perf_ftrace *ftrace) 556 + { 557 + if (ftrace->graph_retval || ftrace->graph_retval_hex) { 558 + if (write_tracing_option_file("funcgraph-retval", "1") < 0) 559 + return -1; 560 + } 561 + 562 + if (ftrace->graph_retval_hex) { 563 + if (write_tracing_option_file("funcgraph-retval-hex", "1") < 0) 564 + return -1; 565 + } 566 + 567 + return 0; 568 + } 569 + 570 + static int set_tracing_funcgraph_retaddr(struct perf_ftrace *ftrace) 571 + { 572 + if (ftrace->graph_retaddr) { 573 + if (write_tracing_option_file("funcgraph-retaddr", "1") < 0) 574 + return -1; 575 + } 576 + 577 + return 0; 578 + } 579 + 549 580 static int set_tracing_funcgraph_irqs(struct perf_ftrace *ftrace) 550 581 { 551 582 if (!ftrace->graph_noirqs) ··· 678 639 679 640 if (set_tracing_sleep_time(ftrace) < 0) { 680 641 pr_err("failed to set tracing option sleep-time\n"); 642 + return -1; 643 + } 644 + 645 + if (set_tracing_funcgraph_args(ftrace) < 0) { 646 + pr_err("failed to set tracing option funcgraph-args\n"); 647 + return -1; 648 + } 649 + 650 + if (set_tracing_funcgraph_retval(ftrace) < 0) { 651 + pr_err("failed to set tracing option funcgraph-retval\n"); 652 + return -1; 653 + } 654 + 655 + if (set_tracing_funcgraph_retaddr(ftrace) < 0) { 656 + pr_err("failed to set tracing option funcgraph-retaddr\n"); 681 657 return -1; 682 658 } 683 659 ··· 1688 1634 int ret; 1689 1635 struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value; 1690 1636 struct sublevel_option graph_tracer_opts[] = { 1637 + { .name = "args", .value_ptr = &ftrace->graph_args }, 1638 + { .name = "retval", .value_ptr = &ftrace->graph_retval }, 1639 + { .name = "retval-hex", .value_ptr = &ftrace->graph_retval_hex }, 1640 + { .name = "retaddr", .value_ptr = &ftrace->graph_retaddr }, 1691 1641 { .name = "nosleep-time", .value_ptr = &ftrace->graph_nosleep_time }, 1692 1642 { .name = "noirqs", .value_ptr = &ftrace->graph_noirqs }, 1693 1643 { .name = "verbose", .value_ptr = &ftrace->graph_verbose }, ··· 1783 1725 OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func", 1784 1726 "Set nograph filter on given functions", parse_filter_func), 1785 1727 OPT_CALLBACK(0, "graph-opts", &ftrace, "options", 1786 - "Graph tracer options, available options: nosleep-time,noirqs,verbose,thresh=<n>,depth=<n>", 1728 + "Graph tracer options, available options: args,retval,retval-hex,retaddr,nosleep-time,noirqs,verbose,thresh=<n>,depth=<n>", 1787 1729 parse_graph_tracer_opts), 1788 1730 OPT_CALLBACK('m', "buffer-size", &ftrace.percpu_buffer_size, "size", 1789 1731 "Size of per cpu buffer, needs to use a B, K, M or G suffix.", parse_buffer_size),
+4
tools/perf/util/ftrace.h
··· 30 30 int graph_depth; 31 31 int func_stack_trace; 32 32 int func_irq_info; 33 + int graph_args; 34 + int graph_retval; 35 + int graph_retval_hex; 36 + int graph_retaddr; 33 37 int graph_nosleep_time; 34 38 int graph_noirqs; 35 39 int graph_verbose;