xref: /linux/tools/perf/builtin-ftrace.c (revision c5d50457a8fc2695ca5a921f3a4a402343cf5313)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * builtin-ftrace.c
4  *
5  * Copyright (c) 2013  LG Electronics,  Namhyung Kim <namhyung@kernel.org>
6  * Copyright (c) 2020  Changbin Du <changbin.du@gmail.com>, significant enhancement.
7  */
8 
9 #include "builtin.h"
10 
11 #include <errno.h>
12 #include <unistd.h>
13 #include <signal.h>
14 #include <stdlib.h>
15 #include <fcntl.h>
16 #include <inttypes.h>
17 #include <math.h>
18 #include <poll.h>
19 #include <ctype.h>
20 #include <linux/capability.h>
21 #include <linux/string.h>
22 
23 #include "debug.h"
24 #include <subcmd/pager.h>
25 #include <subcmd/parse-options.h>
26 #include <api/io.h>
27 #include <api/fs/tracing_path.h>
28 #include "evlist.h"
29 #include "target.h"
30 #include "cpumap.h"
31 #include "hashmap.h"
32 #include "thread_map.h"
33 #include "strfilter.h"
34 #include "util/cap.h"
35 #include "util/config.h"
36 #include "util/ftrace.h"
37 #include "util/stat.h"
38 #include "util/units.h"
39 #include "util/parse-sublevel-options.h"
40 
41 #define DEFAULT_TRACER  "function_graph"
42 
43 static volatile sig_atomic_t workload_exec_errno;
44 static volatile sig_atomic_t done;
45 
46 static void sig_handler(int sig __maybe_unused)
47 {
48 	done = true;
49 }
50 
51 /*
52  * evlist__prepare_workload will send a SIGUSR1 if the fork fails, since
53  * we asked by setting its exec_error to the function below,
54  * ftrace__workload_exec_failed_signal.
55  *
56  * XXX We need to handle this more appropriately, emitting an error, etc.
57  */
58 static void ftrace__workload_exec_failed_signal(int signo __maybe_unused,
59 						siginfo_t *info __maybe_unused,
60 						void *ucontext __maybe_unused)
61 {
62 	workload_exec_errno = info->si_value.sival_int;
63 	done = true;
64 }
65 
66 static bool check_ftrace_capable(void)
67 {
68 	bool used_root;
69 
70 	if (perf_cap__capable(CAP_PERFMON, &used_root))
71 		return true;
72 
73 	if (!used_root && perf_cap__capable(CAP_SYS_ADMIN, &used_root))
74 		return true;
75 
76 	pr_err("ftrace only works for %s!\n",
77 		used_root ? "root"
78 			  : "users with the CAP_PERFMON or CAP_SYS_ADMIN capability"
79 		);
80 	return false;
81 }
82 
83 static int __write_tracing_file(const char *name, const char *val, bool append)
84 {
85 	char *file;
86 	int fd, ret = -1;
87 	ssize_t size = strlen(val);
88 	int flags = O_WRONLY;
89 	char errbuf[512];
90 	char *val_copy;
91 
92 	file = get_tracing_file(name);
93 	if (!file) {
94 		pr_debug("cannot get tracing file: %s\n", name);
95 		return -1;
96 	}
97 
98 	if (append)
99 		flags |= O_APPEND;
100 	else
101 		flags |= O_TRUNC;
102 
103 	fd = open(file, flags);
104 	if (fd < 0) {
105 		pr_debug("cannot open tracing file: %s: %s\n",
106 			 name, str_error_r(errno, errbuf, sizeof(errbuf)));
107 		goto out;
108 	}
109 
110 	/*
111 	 * Copy the original value and append a '\n'. Without this,
112 	 * the kernel can hide possible errors.
113 	 */
114 	val_copy = strdup(val);
115 	if (!val_copy)
116 		goto out_close;
117 	val_copy[size] = '\n';
118 
119 	if (write(fd, val_copy, size + 1) == size + 1)
120 		ret = 0;
121 	else
122 		pr_debug("write '%s' to tracing/%s failed: %s\n",
123 			 val, name, str_error_r(errno, errbuf, sizeof(errbuf)));
124 
125 	free(val_copy);
126 out_close:
127 	close(fd);
128 out:
129 	put_tracing_file(file);
130 	return ret;
131 }
132 
133 static int write_tracing_file(const char *name, const char *val)
134 {
135 	return __write_tracing_file(name, val, false);
136 }
137 
138 static int append_tracing_file(const char *name, const char *val)
139 {
140 	return __write_tracing_file(name, val, true);
141 }
142 
143 static int read_tracing_file_to_stdout(const char *name)
144 {
145 	char buf[4096];
146 	char *file;
147 	int fd;
148 	int ret = -1;
149 
150 	file = get_tracing_file(name);
151 	if (!file) {
152 		pr_debug("cannot get tracing file: %s\n", name);
153 		return -1;
154 	}
155 
156 	fd = open(file, O_RDONLY);
157 	if (fd < 0) {
158 		pr_debug("cannot open tracing file: %s: %s\n",
159 			 name, str_error_r(errno, buf, sizeof(buf)));
160 		goto out;
161 	}
162 
163 	/* read contents to stdout */
164 	while (true) {
165 		int n = read(fd, buf, sizeof(buf));
166 		if (n == 0)
167 			break;
168 		else if (n < 0)
169 			goto out_close;
170 
171 		if (fwrite(buf, n, 1, stdout) != 1)
172 			goto out_close;
173 	}
174 	ret = 0;
175 
176 out_close:
177 	close(fd);
178 out:
179 	put_tracing_file(file);
180 	return ret;
181 }
182 
183 static int read_tracing_file_by_line(const char *name,
184 				     void (*cb)(char *str, void *arg),
185 				     void *cb_arg)
186 {
187 	char *line = NULL;
188 	size_t len = 0;
189 	char *file;
190 	FILE *fp;
191 
192 	file = get_tracing_file(name);
193 	if (!file) {
194 		pr_debug("cannot get tracing file: %s\n", name);
195 		return -1;
196 	}
197 
198 	fp = fopen(file, "r");
199 	if (fp == NULL) {
200 		pr_debug("cannot open tracing file: %s\n", name);
201 		put_tracing_file(file);
202 		return -1;
203 	}
204 
205 	while (getline(&line, &len, fp) != -1) {
206 		cb(line, cb_arg);
207 	}
208 
209 	if (line)
210 		free(line);
211 
212 	fclose(fp);
213 	put_tracing_file(file);
214 	return 0;
215 }
216 
217 static int write_tracing_file_int(const char *name, int value)
218 {
219 	char buf[16];
220 
221 	snprintf(buf, sizeof(buf), "%d", value);
222 	if (write_tracing_file(name, buf) < 0)
223 		return -1;
224 
225 	return 0;
226 }
227 
228 static int write_tracing_option_file(const char *name, const char *val)
229 {
230 	char *file;
231 	int ret;
232 
233 	if (asprintf(&file, "options/%s", name) < 0)
234 		return -1;
235 
236 	ret = __write_tracing_file(file, val, false);
237 	free(file);
238 	return ret;
239 }
240 
241 static int reset_tracing_cpu(void);
242 static void reset_tracing_filters(void);
243 
244 static void reset_tracing_options(struct perf_ftrace *ftrace __maybe_unused)
245 {
246 	write_tracing_option_file("function-fork", "0");
247 	write_tracing_option_file("func_stack_trace", "0");
248 	write_tracing_option_file("sleep-time", "1");
249 	write_tracing_option_file("funcgraph-irqs", "1");
250 	write_tracing_option_file("funcgraph-proc", "0");
251 	write_tracing_option_file("funcgraph-abstime", "0");
252 	write_tracing_option_file("funcgraph-tail", "0");
253 	write_tracing_option_file("latency-format", "0");
254 	write_tracing_option_file("irq-info", "0");
255 }
256 
257 static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
258 {
259 	if (write_tracing_file("tracing_on", "0") < 0)
260 		return -1;
261 
262 	if (write_tracing_file("current_tracer", "nop") < 0)
263 		return -1;
264 
265 	if (write_tracing_file("set_ftrace_pid", " ") < 0)
266 		return -1;
267 
268 	if (reset_tracing_cpu() < 0)
269 		return -1;
270 
271 	if (write_tracing_file("max_graph_depth", "0") < 0)
272 		return -1;
273 
274 	if (write_tracing_file("tracing_thresh", "0") < 0)
275 		return -1;
276 
277 	reset_tracing_filters();
278 	reset_tracing_options(ftrace);
279 	return 0;
280 }
281 
282 static int set_tracing_pid(struct perf_ftrace *ftrace)
283 {
284 	int i;
285 	char buf[16];
286 
287 	if (target__has_cpu(&ftrace->target))
288 		return 0;
289 
290 	for (i = 0; i < perf_thread_map__nr(ftrace->evlist->core.threads); i++) {
291 		scnprintf(buf, sizeof(buf), "%d",
292 			  perf_thread_map__pid(ftrace->evlist->core.threads, i));
293 		if (append_tracing_file("set_ftrace_pid", buf) < 0)
294 			return -1;
295 	}
296 	return 0;
297 }
298 
299 static int set_tracing_cpumask(struct perf_cpu_map *cpumap)
300 {
301 	char *cpumask;
302 	size_t mask_size;
303 	int ret;
304 	int last_cpu;
305 
306 	last_cpu = perf_cpu_map__cpu(cpumap, perf_cpu_map__nr(cpumap) - 1).cpu;
307 	mask_size = last_cpu / 4 + 2; /* one more byte for EOS */
308 	mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */
309 
310 	cpumask = malloc(mask_size);
311 	if (cpumask == NULL) {
312 		pr_debug("failed to allocate cpu mask\n");
313 		return -1;
314 	}
315 
316 	cpu_map__snprint_mask(cpumap, cpumask, mask_size);
317 
318 	ret = write_tracing_file("tracing_cpumask", cpumask);
319 
320 	free(cpumask);
321 	return ret;
322 }
323 
324 static int set_tracing_cpu(struct perf_ftrace *ftrace)
325 {
326 	struct perf_cpu_map *cpumap = ftrace->evlist->core.user_requested_cpus;
327 
328 	if (!target__has_cpu(&ftrace->target))
329 		return 0;
330 
331 	return set_tracing_cpumask(cpumap);
332 }
333 
334 static int set_tracing_func_stack_trace(struct perf_ftrace *ftrace)
335 {
336 	if (!ftrace->func_stack_trace)
337 		return 0;
338 
339 	if (write_tracing_option_file("func_stack_trace", "1") < 0)
340 		return -1;
341 
342 	return 0;
343 }
344 
345 static int set_tracing_func_irqinfo(struct perf_ftrace *ftrace)
346 {
347 	if (!ftrace->func_irq_info)
348 		return 0;
349 
350 	if (write_tracing_option_file("irq-info", "1") < 0)
351 		return -1;
352 
353 	return 0;
354 }
355 
356 static int reset_tracing_cpu(void)
357 {
358 	struct perf_cpu_map *cpumap = perf_cpu_map__new_online_cpus();
359 	int ret;
360 
361 	ret = set_tracing_cpumask(cpumap);
362 	perf_cpu_map__put(cpumap);
363 	return ret;
364 }
365 
366 static int __set_tracing_filter(const char *filter_file, struct list_head *funcs)
367 {
368 	struct filter_entry *pos;
369 
370 	list_for_each_entry(pos, funcs, list) {
371 		if (append_tracing_file(filter_file, pos->name) < 0)
372 			return -1;
373 	}
374 
375 	return 0;
376 }
377 
378 static int set_tracing_filters(struct perf_ftrace *ftrace)
379 {
380 	int ret;
381 
382 	ret = __set_tracing_filter("set_ftrace_filter", &ftrace->filters);
383 	if (ret < 0)
384 		return ret;
385 
386 	ret = __set_tracing_filter("set_ftrace_notrace", &ftrace->notrace);
387 	if (ret < 0)
388 		return ret;
389 
390 	ret = __set_tracing_filter("set_graph_function", &ftrace->graph_funcs);
391 	if (ret < 0)
392 		return ret;
393 
394 	/* old kernels do not have this filter */
395 	__set_tracing_filter("set_graph_notrace", &ftrace->nograph_funcs);
396 
397 	return ret;
398 }
399 
400 static void reset_tracing_filters(void)
401 {
402 	write_tracing_file("set_ftrace_filter", " ");
403 	write_tracing_file("set_ftrace_notrace", " ");
404 	write_tracing_file("set_graph_function", " ");
405 	write_tracing_file("set_graph_notrace", " ");
406 }
407 
408 static int set_tracing_depth(struct perf_ftrace *ftrace)
409 {
410 	if (ftrace->graph_depth == 0)
411 		return 0;
412 
413 	if (ftrace->graph_depth < 0) {
414 		pr_err("invalid graph depth: %d\n", ftrace->graph_depth);
415 		return -1;
416 	}
417 
418 	if (write_tracing_file_int("max_graph_depth", ftrace->graph_depth) < 0)
419 		return -1;
420 
421 	return 0;
422 }
423 
424 static int set_tracing_percpu_buffer_size(struct perf_ftrace *ftrace)
425 {
426 	int ret;
427 
428 	if (ftrace->percpu_buffer_size == 0)
429 		return 0;
430 
431 	ret = write_tracing_file_int("buffer_size_kb",
432 				     ftrace->percpu_buffer_size / 1024);
433 	if (ret < 0)
434 		return ret;
435 
436 	return 0;
437 }
438 
439 static int set_tracing_trace_inherit(struct perf_ftrace *ftrace)
440 {
441 	if (!ftrace->inherit)
442 		return 0;
443 
444 	if (write_tracing_option_file("function-fork", "1") < 0)
445 		return -1;
446 
447 	return 0;
448 }
449 
450 static int set_tracing_sleep_time(struct perf_ftrace *ftrace)
451 {
452 	if (!ftrace->graph_nosleep_time)
453 		return 0;
454 
455 	if (write_tracing_option_file("sleep-time", "0") < 0)
456 		return -1;
457 
458 	return 0;
459 }
460 
461 static int set_tracing_funcgraph_irqs(struct perf_ftrace *ftrace)
462 {
463 	if (!ftrace->graph_noirqs)
464 		return 0;
465 
466 	if (write_tracing_option_file("funcgraph-irqs", "0") < 0)
467 		return -1;
468 
469 	return 0;
470 }
471 
472 static int set_tracing_funcgraph_verbose(struct perf_ftrace *ftrace)
473 {
474 	if (!ftrace->graph_verbose)
475 		return 0;
476 
477 	if (write_tracing_option_file("funcgraph-proc", "1") < 0)
478 		return -1;
479 
480 	if (write_tracing_option_file("funcgraph-abstime", "1") < 0)
481 		return -1;
482 
483 	if (write_tracing_option_file("latency-format", "1") < 0)
484 		return -1;
485 
486 	return 0;
487 }
488 
489 static int set_tracing_funcgraph_tail(struct perf_ftrace *ftrace)
490 {
491 	if (!ftrace->graph_tail)
492 		return 0;
493 
494 	if (write_tracing_option_file("funcgraph-tail", "1") < 0)
495 		return -1;
496 
497 	return 0;
498 }
499 
500 static int set_tracing_thresh(struct perf_ftrace *ftrace)
501 {
502 	int ret;
503 
504 	if (ftrace->graph_thresh == 0)
505 		return 0;
506 
507 	ret = write_tracing_file_int("tracing_thresh", ftrace->graph_thresh);
508 	if (ret < 0)
509 		return ret;
510 
511 	return 0;
512 }
513 
514 static int set_tracing_options(struct perf_ftrace *ftrace)
515 {
516 	if (set_tracing_pid(ftrace) < 0) {
517 		pr_err("failed to set ftrace pid\n");
518 		return -1;
519 	}
520 
521 	if (set_tracing_cpu(ftrace) < 0) {
522 		pr_err("failed to set tracing cpumask\n");
523 		return -1;
524 	}
525 
526 	if (set_tracing_func_stack_trace(ftrace) < 0) {
527 		pr_err("failed to set tracing option func_stack_trace\n");
528 		return -1;
529 	}
530 
531 	if (set_tracing_func_irqinfo(ftrace) < 0) {
532 		pr_err("failed to set tracing option irq-info\n");
533 		return -1;
534 	}
535 
536 	if (set_tracing_filters(ftrace) < 0) {
537 		pr_err("failed to set tracing filters\n");
538 		return -1;
539 	}
540 
541 	if (set_tracing_depth(ftrace) < 0) {
542 		pr_err("failed to set graph depth\n");
543 		return -1;
544 	}
545 
546 	if (set_tracing_percpu_buffer_size(ftrace) < 0) {
547 		pr_err("failed to set tracing per-cpu buffer size\n");
548 		return -1;
549 	}
550 
551 	if (set_tracing_trace_inherit(ftrace) < 0) {
552 		pr_err("failed to set tracing option function-fork\n");
553 		return -1;
554 	}
555 
556 	if (set_tracing_sleep_time(ftrace) < 0) {
557 		pr_err("failed to set tracing option sleep-time\n");
558 		return -1;
559 	}
560 
561 	if (set_tracing_funcgraph_irqs(ftrace) < 0) {
562 		pr_err("failed to set tracing option funcgraph-irqs\n");
563 		return -1;
564 	}
565 
566 	if (set_tracing_funcgraph_verbose(ftrace) < 0) {
567 		pr_err("failed to set tracing option funcgraph-proc/funcgraph-abstime\n");
568 		return -1;
569 	}
570 
571 	if (set_tracing_thresh(ftrace) < 0) {
572 		pr_err("failed to set tracing thresh\n");
573 		return -1;
574 	}
575 
576 	if (set_tracing_funcgraph_tail(ftrace) < 0) {
577 		pr_err("failed to set tracing option funcgraph-tail\n");
578 		return -1;
579 	}
580 
581 	return 0;
582 }
583 
584 static void select_tracer(struct perf_ftrace *ftrace)
585 {
586 	bool graph = !list_empty(&ftrace->graph_funcs) ||
587 		     !list_empty(&ftrace->nograph_funcs);
588 	bool func = !list_empty(&ftrace->filters) ||
589 		    !list_empty(&ftrace->notrace);
590 
591 	/* The function_graph has priority over function tracer. */
592 	if (graph)
593 		ftrace->tracer = "function_graph";
594 	else if (func)
595 		ftrace->tracer = "function";
596 	/* Otherwise, the default tracer is used. */
597 
598 	pr_debug("%s tracer is used\n", ftrace->tracer);
599 }
600 
601 static int __cmd_ftrace(struct perf_ftrace *ftrace)
602 {
603 	char *trace_file;
604 	int trace_fd;
605 	char buf[4096];
606 	struct pollfd pollfd = {
607 		.events = POLLIN,
608 	};
609 
610 	select_tracer(ftrace);
611 
612 	if (reset_tracing_files(ftrace) < 0) {
613 		pr_err("failed to reset ftrace\n");
614 		goto out;
615 	}
616 
617 	/* reset ftrace buffer */
618 	if (write_tracing_file("trace", "0") < 0)
619 		goto out;
620 
621 	if (set_tracing_options(ftrace) < 0)
622 		goto out_reset;
623 
624 	if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
625 		pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
626 		goto out_reset;
627 	}
628 
629 	setup_pager();
630 
631 	trace_file = get_tracing_file("trace_pipe");
632 	if (!trace_file) {
633 		pr_err("failed to open trace_pipe\n");
634 		goto out_reset;
635 	}
636 
637 	trace_fd = open(trace_file, O_RDONLY);
638 
639 	put_tracing_file(trace_file);
640 
641 	if (trace_fd < 0) {
642 		pr_err("failed to open trace_pipe\n");
643 		goto out_reset;
644 	}
645 
646 	fcntl(trace_fd, F_SETFL, O_NONBLOCK);
647 	pollfd.fd = trace_fd;
648 
649 	/* display column headers */
650 	read_tracing_file_to_stdout("trace");
651 
652 	if (!ftrace->target.initial_delay) {
653 		if (write_tracing_file("tracing_on", "1") < 0) {
654 			pr_err("can't enable tracing\n");
655 			goto out_close_fd;
656 		}
657 	}
658 
659 	evlist__start_workload(ftrace->evlist);
660 
661 	if (ftrace->target.initial_delay > 0) {
662 		usleep(ftrace->target.initial_delay * 1000);
663 		if (write_tracing_file("tracing_on", "1") < 0) {
664 			pr_err("can't enable tracing\n");
665 			goto out_close_fd;
666 		}
667 	}
668 
669 	while (!done) {
670 		if (poll(&pollfd, 1, -1) < 0)
671 			break;
672 
673 		if (pollfd.revents & POLLIN) {
674 			int n = read(trace_fd, buf, sizeof(buf));
675 			if (n < 0)
676 				break;
677 			if (fwrite(buf, n, 1, stdout) != 1)
678 				break;
679 			/* flush output since stdout is in full buffering mode due to pager */
680 			fflush(stdout);
681 		}
682 	}
683 
684 	write_tracing_file("tracing_on", "0");
685 
686 	if (workload_exec_errno) {
687 		const char *emsg = str_error_r(workload_exec_errno, buf, sizeof(buf));
688 		/* flush stdout first so below error msg appears at the end. */
689 		fflush(stdout);
690 		pr_err("workload failed: %s\n", emsg);
691 		goto out_close_fd;
692 	}
693 
694 	/* read remaining buffer contents */
695 	while (true) {
696 		int n = read(trace_fd, buf, sizeof(buf));
697 		if (n <= 0)
698 			break;
699 		if (fwrite(buf, n, 1, stdout) != 1)
700 			break;
701 	}
702 
703 out_close_fd:
704 	close(trace_fd);
705 out_reset:
706 	reset_tracing_files(ftrace);
707 out:
708 	return (done && !workload_exec_errno) ? 0 : -1;
709 }
710 
711 static void make_histogram(int buckets[], char *buf, size_t len, char *linebuf,
712 			   bool use_nsec)
713 {
714 	char *p, *q;
715 	char *unit;
716 	double num;
717 	int i;
718 
719 	/* ensure NUL termination */
720 	buf[len] = '\0';
721 
722 	/* handle data line by line */
723 	for (p = buf; (q = strchr(p, '\n')) != NULL; p = q + 1) {
724 		*q = '\0';
725 		/* move it to the line buffer */
726 		strcat(linebuf, p);
727 
728 		/*
729 		 * parse trace output to get function duration like in
730 		 *
731 		 * # tracer: function_graph
732 		 * #
733 		 * # CPU  DURATION                  FUNCTION CALLS
734 		 * # |     |   |                     |   |   |   |
735 		 *  1) + 10.291 us   |  do_filp_open();
736 		 *  1)   4.889 us    |  do_filp_open();
737 		 *  1)   6.086 us    |  do_filp_open();
738 		 *
739 		 */
740 		if (linebuf[0] == '#')
741 			goto next;
742 
743 		/* ignore CPU */
744 		p = strchr(linebuf, ')');
745 		if (p == NULL)
746 			p = linebuf;
747 
748 		while (*p && !isdigit(*p) && (*p != '|'))
749 			p++;
750 
751 		/* no duration */
752 		if (*p == '\0' || *p == '|')
753 			goto next;
754 
755 		num = strtod(p, &unit);
756 		if (!unit || strncmp(unit, " us", 3))
757 			goto next;
758 
759 		if (use_nsec)
760 			num *= 1000;
761 
762 		i = log2(num);
763 		if (i < 0)
764 			i = 0;
765 		if (i >= NUM_BUCKET)
766 			i = NUM_BUCKET - 1;
767 
768 		buckets[i]++;
769 
770 next:
771 		/* empty the line buffer for the next output  */
772 		linebuf[0] = '\0';
773 	}
774 
775 	/* preserve any remaining output (before newline) */
776 	strcat(linebuf, p);
777 }
778 
779 static void display_histogram(int buckets[], bool use_nsec)
780 {
781 	int i;
782 	int total = 0;
783 	int bar_total = 46;  /* to fit in 80 column */
784 	char bar[] = "###############################################";
785 	int bar_len;
786 
787 	for (i = 0; i < NUM_BUCKET; i++)
788 		total += buckets[i];
789 
790 	if (total == 0) {
791 		printf("No data found\n");
792 		return;
793 	}
794 
795 	printf("# %14s | %10s | %-*s |\n",
796 	       "  DURATION    ", "COUNT", bar_total, "GRAPH");
797 
798 	bar_len = buckets[0] * bar_total / total;
799 	printf("  %4d - %-4d %s | %10d | %.*s%*s |\n",
800 	       0, 1, "us", buckets[0], bar_len, bar, bar_total - bar_len, "");
801 
802 	for (i = 1; i < NUM_BUCKET - 1; i++) {
803 		int start = (1 << (i - 1));
804 		int stop = 1 << i;
805 		const char *unit = use_nsec ? "ns" : "us";
806 
807 		if (start >= 1024) {
808 			start >>= 10;
809 			stop >>= 10;
810 			unit = use_nsec ? "us" : "ms";
811 		}
812 		bar_len = buckets[i] * bar_total / total;
813 		printf("  %4d - %-4d %s | %10d | %.*s%*s |\n",
814 		       start, stop, unit, buckets[i], bar_len, bar,
815 		       bar_total - bar_len, "");
816 	}
817 
818 	bar_len = buckets[NUM_BUCKET - 1] * bar_total / total;
819 	printf("  %4d - %-4s %s | %10d | %.*s%*s |\n",
820 	       1, "...", use_nsec ? "ms" : " s", buckets[NUM_BUCKET - 1],
821 	       bar_len, bar, bar_total - bar_len, "");
822 
823 }
824 
825 static int prepare_func_latency(struct perf_ftrace *ftrace)
826 {
827 	char *trace_file;
828 	int fd;
829 
830 	if (ftrace->target.use_bpf)
831 		return perf_ftrace__latency_prepare_bpf(ftrace);
832 
833 	if (reset_tracing_files(ftrace) < 0) {
834 		pr_err("failed to reset ftrace\n");
835 		return -1;
836 	}
837 
838 	/* reset ftrace buffer */
839 	if (write_tracing_file("trace", "0") < 0)
840 		return -1;
841 
842 	if (set_tracing_options(ftrace) < 0)
843 		return -1;
844 
845 	/* force to use the function_graph tracer to track duration */
846 	if (write_tracing_file("current_tracer", "function_graph") < 0) {
847 		pr_err("failed to set current_tracer to function_graph\n");
848 		return -1;
849 	}
850 
851 	trace_file = get_tracing_file("trace_pipe");
852 	if (!trace_file) {
853 		pr_err("failed to open trace_pipe\n");
854 		return -1;
855 	}
856 
857 	fd = open(trace_file, O_RDONLY);
858 	if (fd < 0)
859 		pr_err("failed to open trace_pipe\n");
860 
861 	put_tracing_file(trace_file);
862 	return fd;
863 }
864 
865 static int start_func_latency(struct perf_ftrace *ftrace)
866 {
867 	if (ftrace->target.use_bpf)
868 		return perf_ftrace__latency_start_bpf(ftrace);
869 
870 	if (write_tracing_file("tracing_on", "1") < 0) {
871 		pr_err("can't enable tracing\n");
872 		return -1;
873 	}
874 
875 	return 0;
876 }
877 
878 static int stop_func_latency(struct perf_ftrace *ftrace)
879 {
880 	if (ftrace->target.use_bpf)
881 		return perf_ftrace__latency_stop_bpf(ftrace);
882 
883 	write_tracing_file("tracing_on", "0");
884 	return 0;
885 }
886 
887 static int read_func_latency(struct perf_ftrace *ftrace, int buckets[])
888 {
889 	if (ftrace->target.use_bpf)
890 		return perf_ftrace__latency_read_bpf(ftrace, buckets);
891 
892 	return 0;
893 }
894 
895 static int cleanup_func_latency(struct perf_ftrace *ftrace)
896 {
897 	if (ftrace->target.use_bpf)
898 		return perf_ftrace__latency_cleanup_bpf(ftrace);
899 
900 	reset_tracing_files(ftrace);
901 	return 0;
902 }
903 
904 static int __cmd_latency(struct perf_ftrace *ftrace)
905 {
906 	int trace_fd;
907 	char buf[4096];
908 	char line[256];
909 	struct pollfd pollfd = {
910 		.events = POLLIN,
911 	};
912 	int buckets[NUM_BUCKET] = { };
913 
914 	trace_fd = prepare_func_latency(ftrace);
915 	if (trace_fd < 0)
916 		goto out;
917 
918 	fcntl(trace_fd, F_SETFL, O_NONBLOCK);
919 	pollfd.fd = trace_fd;
920 
921 	if (start_func_latency(ftrace) < 0)
922 		goto out;
923 
924 	evlist__start_workload(ftrace->evlist);
925 
926 	line[0] = '\0';
927 	while (!done) {
928 		if (poll(&pollfd, 1, -1) < 0)
929 			break;
930 
931 		if (pollfd.revents & POLLIN) {
932 			int n = read(trace_fd, buf, sizeof(buf) - 1);
933 			if (n < 0)
934 				break;
935 
936 			make_histogram(buckets, buf, n, line, ftrace->use_nsec);
937 		}
938 	}
939 
940 	stop_func_latency(ftrace);
941 
942 	if (workload_exec_errno) {
943 		const char *emsg = str_error_r(workload_exec_errno, buf, sizeof(buf));
944 		pr_err("workload failed: %s\n", emsg);
945 		goto out;
946 	}
947 
948 	/* read remaining buffer contents */
949 	while (!ftrace->target.use_bpf) {
950 		int n = read(trace_fd, buf, sizeof(buf) - 1);
951 		if (n <= 0)
952 			break;
953 		make_histogram(buckets, buf, n, line, ftrace->use_nsec);
954 	}
955 
956 	read_func_latency(ftrace, buckets);
957 
958 	display_histogram(buckets, ftrace->use_nsec);
959 
960 out:
961 	close(trace_fd);
962 	cleanup_func_latency(ftrace);
963 
964 	return (done && !workload_exec_errno) ? 0 : -1;
965 }
966 
967 static size_t profile_hash(long func, void *ctx __maybe_unused)
968 {
969 	return str_hash((char *)func);
970 }
971 
972 static bool profile_equal(long func1, long func2, void *ctx __maybe_unused)
973 {
974 	return !strcmp((char *)func1, (char *)func2);
975 }
976 
977 static int prepare_func_profile(struct perf_ftrace *ftrace)
978 {
979 	ftrace->tracer = "function_graph";
980 	ftrace->graph_tail = 1;
981 
982 	ftrace->profile_hash = hashmap__new(profile_hash, profile_equal, NULL);
983 	if (ftrace->profile_hash == NULL)
984 		return -ENOMEM;
985 
986 	return 0;
987 }
988 
989 /* This is saved in a hashmap keyed by the function name */
990 struct ftrace_profile_data {
991 	struct stats st;
992 };
993 
994 static int add_func_duration(struct perf_ftrace *ftrace, char *func, double time_ns)
995 {
996 	struct ftrace_profile_data *prof = NULL;
997 
998 	if (!hashmap__find(ftrace->profile_hash, func, &prof)) {
999 		char *key = strdup(func);
1000 
1001 		if (key == NULL)
1002 			return -ENOMEM;
1003 
1004 		prof = zalloc(sizeof(*prof));
1005 		if (prof == NULL) {
1006 			free(key);
1007 			return -ENOMEM;
1008 		}
1009 
1010 		init_stats(&prof->st);
1011 		hashmap__add(ftrace->profile_hash, key, prof);
1012 	}
1013 
1014 	update_stats(&prof->st, time_ns);
1015 	return 0;
1016 }
1017 
1018 /*
1019  * The ftrace function_graph text output normally looks like below:
1020  *
1021  * CPU   DURATION       FUNCTION
1022  *
1023  *  0)               |  syscall_trace_enter.isra.0() {
1024  *  0)               |    __audit_syscall_entry() {
1025  *  0)               |      auditd_test_task() {
1026  *  0)   0.271 us    |        __rcu_read_lock();
1027  *  0)   0.275 us    |        __rcu_read_unlock();
1028  *  0)   1.254 us    |      } /\* auditd_test_task *\/
1029  *  0)   0.279 us    |      ktime_get_coarse_real_ts64();
1030  *  0)   2.227 us    |    } /\* __audit_syscall_entry *\/
1031  *  0)   2.713 us    |  } /\* syscall_trace_enter.isra.0 *\/
1032  *
1033  *  Parse the line and get the duration and function name.
1034  */
1035 static int parse_func_duration(struct perf_ftrace *ftrace, char *line, size_t len)
1036 {
1037 	char *p;
1038 	char *func;
1039 	double duration;
1040 
1041 	/* skip CPU */
1042 	p = strchr(line, ')');
1043 	if (p == NULL)
1044 		return 0;
1045 
1046 	/* get duration */
1047 	p = skip_spaces(p + 1);
1048 
1049 	/* no duration? */
1050 	if (p == NULL || *p == '|')
1051 		return 0;
1052 
1053 	/* skip markers like '*' or '!' for longer than ms */
1054 	if (!isdigit(*p))
1055 		p++;
1056 
1057 	duration = strtod(p, &p);
1058 
1059 	if (strncmp(p, " us", 3)) {
1060 		pr_debug("non-usec time found.. ignoring\n");
1061 		return 0;
1062 	}
1063 
1064 	/*
1065 	 * profile stat keeps the max and min values as integer,
1066 	 * convert to nsec time so that we can have accurate max.
1067 	 */
1068 	duration *= 1000;
1069 
1070 	/* skip to the pipe */
1071 	while (p < line + len && *p != '|')
1072 		p++;
1073 
1074 	if (*p++ != '|')
1075 		return -EINVAL;
1076 
1077 	/* get function name */
1078 	func = skip_spaces(p);
1079 
1080 	/* skip the closing bracket and the start of comment */
1081 	if (*func == '}')
1082 		func += 5;
1083 
1084 	/* remove semi-colon or end of comment at the end */
1085 	p = line + len - 1;
1086 	while (!isalnum(*p) && *p != ']') {
1087 		*p = '\0';
1088 		--p;
1089 	}
1090 
1091 	return add_func_duration(ftrace, func, duration);
1092 }
1093 
1094 enum perf_ftrace_profile_sort_key {
1095 	PFP_SORT_TOTAL = 0,
1096 	PFP_SORT_AVG,
1097 	PFP_SORT_MAX,
1098 	PFP_SORT_COUNT,
1099 	PFP_SORT_NAME,
1100 };
1101 
1102 static enum perf_ftrace_profile_sort_key profile_sort = PFP_SORT_TOTAL;
1103 
1104 static int cmp_profile_data(const void *a, const void *b)
1105 {
1106 	const struct hashmap_entry *e1 = *(const struct hashmap_entry **)a;
1107 	const struct hashmap_entry *e2 = *(const struct hashmap_entry **)b;
1108 	struct ftrace_profile_data *p1 = e1->pvalue;
1109 	struct ftrace_profile_data *p2 = e2->pvalue;
1110 	double v1, v2;
1111 
1112 	switch (profile_sort) {
1113 	case PFP_SORT_NAME:
1114 		return strcmp(e1->pkey, e2->pkey);
1115 	case PFP_SORT_AVG:
1116 		v1 = p1->st.mean;
1117 		v2 = p2->st.mean;
1118 		break;
1119 	case PFP_SORT_MAX:
1120 		v1 = p1->st.max;
1121 		v2 = p2->st.max;
1122 		break;
1123 	case PFP_SORT_COUNT:
1124 		v1 = p1->st.n;
1125 		v2 = p2->st.n;
1126 		break;
1127 	case PFP_SORT_TOTAL:
1128 	default:
1129 		v1 = p1->st.n * p1->st.mean;
1130 		v2 = p2->st.n * p2->st.mean;
1131 		break;
1132 	}
1133 
1134 	if (v1 > v2)
1135 		return -1;
1136 	else
1137 		return 1;
1138 }
1139 
1140 static void print_profile_result(struct perf_ftrace *ftrace)
1141 {
1142 	struct hashmap_entry *entry, **profile;
1143 	size_t i, nr, bkt;
1144 
1145 	nr = hashmap__size(ftrace->profile_hash);
1146 	if (nr == 0)
1147 		return;
1148 
1149 	profile = calloc(nr, sizeof(*profile));
1150 	if (profile == NULL) {
1151 		pr_err("failed to allocate memory for the result\n");
1152 		return;
1153 	}
1154 
1155 	i = 0;
1156 	hashmap__for_each_entry(ftrace->profile_hash, entry, bkt)
1157 		profile[i++] = entry;
1158 
1159 	assert(i == nr);
1160 
1161 	//cmp_profile_data(profile[0], profile[1]);
1162 	qsort(profile, nr, sizeof(*profile), cmp_profile_data);
1163 
1164 	printf("# %10s %10s %10s %10s   %s\n",
1165 	       "Total (us)", "Avg (us)", "Max (us)", "Count", "Function");
1166 
1167 	for (i = 0; i < nr; i++) {
1168 		const char *name = profile[i]->pkey;
1169 		struct ftrace_profile_data *p = profile[i]->pvalue;
1170 
1171 		printf("%12.3f %10.3f %6"PRIu64".%03"PRIu64" %10.0f   %s\n",
1172 		       p->st.n * p->st.mean / 1000, p->st.mean / 1000,
1173 		       p->st.max / 1000, p->st.max % 1000, p->st.n, name);
1174 	}
1175 
1176 	free(profile);
1177 
1178 	hashmap__for_each_entry(ftrace->profile_hash, entry, bkt) {
1179 		free((char *)entry->pkey);
1180 		free(entry->pvalue);
1181 	}
1182 
1183 	hashmap__free(ftrace->profile_hash);
1184 	ftrace->profile_hash = NULL;
1185 }
1186 
1187 static int __cmd_profile(struct perf_ftrace *ftrace)
1188 {
1189 	char *trace_file;
1190 	int trace_fd;
1191 	char buf[4096];
1192 	struct io io;
1193 	char *line = NULL;
1194 	size_t line_len = 0;
1195 
1196 	if (prepare_func_profile(ftrace) < 0) {
1197 		pr_err("failed to prepare func profiler\n");
1198 		goto out;
1199 	}
1200 
1201 	if (reset_tracing_files(ftrace) < 0) {
1202 		pr_err("failed to reset ftrace\n");
1203 		goto out;
1204 	}
1205 
1206 	/* reset ftrace buffer */
1207 	if (write_tracing_file("trace", "0") < 0)
1208 		goto out;
1209 
1210 	if (set_tracing_options(ftrace) < 0)
1211 		return -1;
1212 
1213 	if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
1214 		pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
1215 		goto out_reset;
1216 	}
1217 
1218 	setup_pager();
1219 
1220 	trace_file = get_tracing_file("trace_pipe");
1221 	if (!trace_file) {
1222 		pr_err("failed to open trace_pipe\n");
1223 		goto out_reset;
1224 	}
1225 
1226 	trace_fd = open(trace_file, O_RDONLY);
1227 
1228 	put_tracing_file(trace_file);
1229 
1230 	if (trace_fd < 0) {
1231 		pr_err("failed to open trace_pipe\n");
1232 		goto out_reset;
1233 	}
1234 
1235 	fcntl(trace_fd, F_SETFL, O_NONBLOCK);
1236 
1237 	if (write_tracing_file("tracing_on", "1") < 0) {
1238 		pr_err("can't enable tracing\n");
1239 		goto out_close_fd;
1240 	}
1241 
1242 	evlist__start_workload(ftrace->evlist);
1243 
1244 	io__init(&io, trace_fd, buf, sizeof(buf));
1245 	io.timeout_ms = -1;
1246 
1247 	while (!done && !io.eof) {
1248 		if (io__getline(&io, &line, &line_len) < 0)
1249 			break;
1250 
1251 		if (parse_func_duration(ftrace, line, line_len) < 0)
1252 			break;
1253 	}
1254 
1255 	write_tracing_file("tracing_on", "0");
1256 
1257 	if (workload_exec_errno) {
1258 		const char *emsg = str_error_r(workload_exec_errno, buf, sizeof(buf));
1259 		/* flush stdout first so below error msg appears at the end. */
1260 		fflush(stdout);
1261 		pr_err("workload failed: %s\n", emsg);
1262 		goto out_free_line;
1263 	}
1264 
1265 	/* read remaining buffer contents */
1266 	io.timeout_ms = 0;
1267 	while (!io.eof) {
1268 		if (io__getline(&io, &line, &line_len) < 0)
1269 			break;
1270 
1271 		if (parse_func_duration(ftrace, line, line_len) < 0)
1272 			break;
1273 	}
1274 
1275 	print_profile_result(ftrace);
1276 
1277 out_free_line:
1278 	free(line);
1279 out_close_fd:
1280 	close(trace_fd);
1281 out_reset:
1282 	reset_tracing_files(ftrace);
1283 out:
1284 	return (done && !workload_exec_errno) ? 0 : -1;
1285 }
1286 
1287 static int perf_ftrace_config(const char *var, const char *value, void *cb)
1288 {
1289 	struct perf_ftrace *ftrace = cb;
1290 
1291 	if (!strstarts(var, "ftrace."))
1292 		return 0;
1293 
1294 	if (strcmp(var, "ftrace.tracer"))
1295 		return -1;
1296 
1297 	if (!strcmp(value, "function_graph") ||
1298 	    !strcmp(value, "function")) {
1299 		ftrace->tracer = value;
1300 		return 0;
1301 	}
1302 
1303 	pr_err("Please select \"function_graph\" (default) or \"function\"\n");
1304 	return -1;
1305 }
1306 
1307 static void list_function_cb(char *str, void *arg)
1308 {
1309 	struct strfilter *filter = (struct strfilter *)arg;
1310 
1311 	if (strfilter__compare(filter, str))
1312 		printf("%s", str);
1313 }
1314 
1315 static int opt_list_avail_functions(const struct option *opt __maybe_unused,
1316 				    const char *str, int unset)
1317 {
1318 	struct strfilter *filter;
1319 	const char *err = NULL;
1320 	int ret;
1321 
1322 	if (unset || !str)
1323 		return -1;
1324 
1325 	filter = strfilter__new(str, &err);
1326 	if (!filter)
1327 		return err ? -EINVAL : -ENOMEM;
1328 
1329 	ret = strfilter__or(filter, str, &err);
1330 	if (ret == -EINVAL) {
1331 		pr_err("Filter parse error at %td.\n", err - str + 1);
1332 		pr_err("Source: \"%s\"\n", str);
1333 		pr_err("         %*c\n", (int)(err - str + 1), '^');
1334 		strfilter__delete(filter);
1335 		return ret;
1336 	}
1337 
1338 	ret = read_tracing_file_by_line("available_filter_functions",
1339 					list_function_cb, filter);
1340 	strfilter__delete(filter);
1341 	if (ret < 0)
1342 		return ret;
1343 
1344 	exit(0);
1345 }
1346 
1347 static int parse_filter_func(const struct option *opt, const char *str,
1348 			     int unset __maybe_unused)
1349 {
1350 	struct list_head *head = opt->value;
1351 	struct filter_entry *entry;
1352 
1353 	entry = malloc(sizeof(*entry) + strlen(str) + 1);
1354 	if (entry == NULL)
1355 		return -ENOMEM;
1356 
1357 	strcpy(entry->name, str);
1358 	list_add_tail(&entry->list, head);
1359 
1360 	return 0;
1361 }
1362 
1363 static void delete_filter_func(struct list_head *head)
1364 {
1365 	struct filter_entry *pos, *tmp;
1366 
1367 	list_for_each_entry_safe(pos, tmp, head, list) {
1368 		list_del_init(&pos->list);
1369 		free(pos);
1370 	}
1371 }
1372 
1373 static int parse_buffer_size(const struct option *opt,
1374 			     const char *str, int unset)
1375 {
1376 	unsigned long *s = (unsigned long *)opt->value;
1377 	static struct parse_tag tags_size[] = {
1378 		{ .tag  = 'B', .mult = 1       },
1379 		{ .tag  = 'K', .mult = 1 << 10 },
1380 		{ .tag  = 'M', .mult = 1 << 20 },
1381 		{ .tag  = 'G', .mult = 1 << 30 },
1382 		{ .tag  = 0 },
1383 	};
1384 	unsigned long val;
1385 
1386 	if (unset) {
1387 		*s = 0;
1388 		return 0;
1389 	}
1390 
1391 	val = parse_tag_value(str, tags_size);
1392 	if (val != (unsigned long) -1) {
1393 		if (val < 1024) {
1394 			pr_err("buffer size too small, must larger than 1KB.");
1395 			return -1;
1396 		}
1397 		*s = val;
1398 		return 0;
1399 	}
1400 
1401 	return -1;
1402 }
1403 
1404 static int parse_func_tracer_opts(const struct option *opt,
1405 				  const char *str, int unset)
1406 {
1407 	int ret;
1408 	struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value;
1409 	struct sublevel_option func_tracer_opts[] = {
1410 		{ .name = "call-graph",	.value_ptr = &ftrace->func_stack_trace },
1411 		{ .name = "irq-info",	.value_ptr = &ftrace->func_irq_info },
1412 		{ .name = NULL, }
1413 	};
1414 
1415 	if (unset)
1416 		return 0;
1417 
1418 	ret = perf_parse_sublevel_options(str, func_tracer_opts);
1419 	if (ret)
1420 		return ret;
1421 
1422 	return 0;
1423 }
1424 
1425 static int parse_graph_tracer_opts(const struct option *opt,
1426 				  const char *str, int unset)
1427 {
1428 	int ret;
1429 	struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value;
1430 	struct sublevel_option graph_tracer_opts[] = {
1431 		{ .name = "nosleep-time",	.value_ptr = &ftrace->graph_nosleep_time },
1432 		{ .name = "noirqs",		.value_ptr = &ftrace->graph_noirqs },
1433 		{ .name = "verbose",		.value_ptr = &ftrace->graph_verbose },
1434 		{ .name = "thresh",		.value_ptr = &ftrace->graph_thresh },
1435 		{ .name = "depth",		.value_ptr = &ftrace->graph_depth },
1436 		{ .name = "tail",		.value_ptr = &ftrace->graph_tail },
1437 		{ .name = NULL, }
1438 	};
1439 
1440 	if (unset)
1441 		return 0;
1442 
1443 	ret = perf_parse_sublevel_options(str, graph_tracer_opts);
1444 	if (ret)
1445 		return ret;
1446 
1447 	return 0;
1448 }
1449 
1450 static int parse_sort_key(const struct option *opt, const char *str, int unset)
1451 {
1452 	enum perf_ftrace_profile_sort_key *key = (void *)opt->value;
1453 
1454 	if (unset)
1455 		return 0;
1456 
1457 	if (!strcmp(str, "total"))
1458 		*key = PFP_SORT_TOTAL;
1459 	else if (!strcmp(str, "avg"))
1460 		*key = PFP_SORT_AVG;
1461 	else if (!strcmp(str, "max"))
1462 		*key = PFP_SORT_MAX;
1463 	else if (!strcmp(str, "count"))
1464 		*key = PFP_SORT_COUNT;
1465 	else if (!strcmp(str, "name"))
1466 		*key = PFP_SORT_NAME;
1467 	else {
1468 		pr_err("Unknown sort key: %s\n", str);
1469 		return -1;
1470 	}
1471 	return 0;
1472 }
1473 
1474 enum perf_ftrace_subcommand {
1475 	PERF_FTRACE_NONE,
1476 	PERF_FTRACE_TRACE,
1477 	PERF_FTRACE_LATENCY,
1478 	PERF_FTRACE_PROFILE,
1479 };
1480 
1481 int cmd_ftrace(int argc, const char **argv)
1482 {
1483 	int ret;
1484 	int (*cmd_func)(struct perf_ftrace *) = NULL;
1485 	struct perf_ftrace ftrace = {
1486 		.tracer = DEFAULT_TRACER,
1487 		.target = { .uid = UINT_MAX, },
1488 	};
1489 	const struct option common_options[] = {
1490 	OPT_STRING('p', "pid", &ftrace.target.pid, "pid",
1491 		   "Trace on existing process id"),
1492 	/* TODO: Add short option -t after -t/--tracer can be removed. */
1493 	OPT_STRING(0, "tid", &ftrace.target.tid, "tid",
1494 		   "Trace on existing thread id (exclusive to --pid)"),
1495 	OPT_INCR('v', "verbose", &verbose,
1496 		 "Be more verbose"),
1497 	OPT_BOOLEAN('a', "all-cpus", &ftrace.target.system_wide,
1498 		    "System-wide collection from all CPUs"),
1499 	OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu",
1500 		    "List of cpus to monitor"),
1501 	OPT_END()
1502 	};
1503 	const struct option ftrace_options[] = {
1504 	OPT_STRING('t', "tracer", &ftrace.tracer, "tracer",
1505 		   "Tracer to use: function_graph(default) or function"),
1506 	OPT_CALLBACK_DEFAULT('F', "funcs", NULL, "[FILTER]",
1507 			     "Show available functions to filter",
1508 			     opt_list_avail_functions, "*"),
1509 	OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
1510 		     "Trace given functions using function tracer",
1511 		     parse_filter_func),
1512 	OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
1513 		     "Do not trace given functions", parse_filter_func),
1514 	OPT_CALLBACK(0, "func-opts", &ftrace, "options",
1515 		     "Function tracer options, available options: call-graph,irq-info",
1516 		     parse_func_tracer_opts),
1517 	OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
1518 		     "Trace given functions using function_graph tracer",
1519 		     parse_filter_func),
1520 	OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
1521 		     "Set nograph filter on given functions", parse_filter_func),
1522 	OPT_CALLBACK(0, "graph-opts", &ftrace, "options",
1523 		     "Graph tracer options, available options: nosleep-time,noirqs,verbose,thresh=<n>,depth=<n>",
1524 		     parse_graph_tracer_opts),
1525 	OPT_CALLBACK('m', "buffer-size", &ftrace.percpu_buffer_size, "size",
1526 		     "Size of per cpu buffer, needs to use a B, K, M or G suffix.", parse_buffer_size),
1527 	OPT_BOOLEAN(0, "inherit", &ftrace.inherit,
1528 		    "Trace children processes"),
1529 	OPT_INTEGER('D', "delay", &ftrace.target.initial_delay,
1530 		    "Number of milliseconds to wait before starting tracing after program start"),
1531 	OPT_PARENT(common_options),
1532 	};
1533 	const struct option latency_options[] = {
1534 	OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
1535 		     "Show latency of given function", parse_filter_func),
1536 #ifdef HAVE_BPF_SKEL
1537 	OPT_BOOLEAN('b', "use-bpf", &ftrace.target.use_bpf,
1538 		    "Use BPF to measure function latency"),
1539 #endif
1540 	OPT_BOOLEAN('n', "use-nsec", &ftrace.use_nsec,
1541 		    "Use nano-second histogram"),
1542 	OPT_PARENT(common_options),
1543 	};
1544 	const struct option profile_options[] = {
1545 	OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
1546 		     "Trace given functions using function tracer",
1547 		     parse_filter_func),
1548 	OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
1549 		     "Do not trace given functions", parse_filter_func),
1550 	OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
1551 		     "Trace given functions using function_graph tracer",
1552 		     parse_filter_func),
1553 	OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
1554 		     "Set nograph filter on given functions", parse_filter_func),
1555 	OPT_CALLBACK('m', "buffer-size", &ftrace.percpu_buffer_size, "size",
1556 		     "Size of per cpu buffer, needs to use a B, K, M or G suffix.", parse_buffer_size),
1557 	OPT_CALLBACK('s', "sort", &profile_sort, "key",
1558 		     "Sort result by key: total (default), avg, max, count, name.",
1559 		     parse_sort_key),
1560 	OPT_PARENT(common_options),
1561 	};
1562 	const struct option *options = ftrace_options;
1563 
1564 	const char * const ftrace_usage[] = {
1565 		"perf ftrace [<options>] [<command>]",
1566 		"perf ftrace [<options>] -- [<command>] [<options>]",
1567 		"perf ftrace {trace|latency|profile} [<options>] [<command>]",
1568 		"perf ftrace {trace|latency|profile} [<options>] -- [<command>] [<options>]",
1569 		NULL
1570 	};
1571 	enum perf_ftrace_subcommand subcmd = PERF_FTRACE_NONE;
1572 
1573 	INIT_LIST_HEAD(&ftrace.filters);
1574 	INIT_LIST_HEAD(&ftrace.notrace);
1575 	INIT_LIST_HEAD(&ftrace.graph_funcs);
1576 	INIT_LIST_HEAD(&ftrace.nograph_funcs);
1577 
1578 	signal(SIGINT, sig_handler);
1579 	signal(SIGUSR1, sig_handler);
1580 	signal(SIGCHLD, sig_handler);
1581 	signal(SIGPIPE, sig_handler);
1582 
1583 	if (!check_ftrace_capable())
1584 		return -1;
1585 
1586 	ret = perf_config(perf_ftrace_config, &ftrace);
1587 	if (ret < 0)
1588 		return -1;
1589 
1590 	if (argc > 1) {
1591 		if (!strcmp(argv[1], "trace")) {
1592 			subcmd = PERF_FTRACE_TRACE;
1593 		} else if (!strcmp(argv[1], "latency")) {
1594 			subcmd = PERF_FTRACE_LATENCY;
1595 			options = latency_options;
1596 		} else if (!strcmp(argv[1], "profile")) {
1597 			subcmd = PERF_FTRACE_PROFILE;
1598 			options = profile_options;
1599 		}
1600 
1601 		if (subcmd != PERF_FTRACE_NONE) {
1602 			argc--;
1603 			argv++;
1604 		}
1605 	}
1606 	/* for backward compatibility */
1607 	if (subcmd == PERF_FTRACE_NONE)
1608 		subcmd = PERF_FTRACE_TRACE;
1609 
1610 	argc = parse_options(argc, argv, options, ftrace_usage,
1611 			    PARSE_OPT_STOP_AT_NON_OPTION);
1612 	if (argc < 0) {
1613 		ret = -EINVAL;
1614 		goto out_delete_filters;
1615 	}
1616 
1617 	/* Make system wide (-a) the default target. */
1618 	if (!argc && target__none(&ftrace.target))
1619 		ftrace.target.system_wide = true;
1620 
1621 	switch (subcmd) {
1622 	case PERF_FTRACE_TRACE:
1623 		cmd_func = __cmd_ftrace;
1624 		break;
1625 	case PERF_FTRACE_LATENCY:
1626 		if (list_empty(&ftrace.filters)) {
1627 			pr_err("Should provide a function to measure\n");
1628 			parse_options_usage(ftrace_usage, options, "T", 1);
1629 			ret = -EINVAL;
1630 			goto out_delete_filters;
1631 		}
1632 		cmd_func = __cmd_latency;
1633 		break;
1634 	case PERF_FTRACE_PROFILE:
1635 		cmd_func = __cmd_profile;
1636 		break;
1637 	case PERF_FTRACE_NONE:
1638 	default:
1639 		pr_err("Invalid subcommand\n");
1640 		ret = -EINVAL;
1641 		goto out_delete_filters;
1642 	}
1643 
1644 	ret = target__validate(&ftrace.target);
1645 	if (ret) {
1646 		char errbuf[512];
1647 
1648 		target__strerror(&ftrace.target, ret, errbuf, 512);
1649 		pr_err("%s\n", errbuf);
1650 		goto out_delete_filters;
1651 	}
1652 
1653 	ftrace.evlist = evlist__new();
1654 	if (ftrace.evlist == NULL) {
1655 		ret = -ENOMEM;
1656 		goto out_delete_filters;
1657 	}
1658 
1659 	ret = evlist__create_maps(ftrace.evlist, &ftrace.target);
1660 	if (ret < 0)
1661 		goto out_delete_evlist;
1662 
1663 	if (argc) {
1664 		ret = evlist__prepare_workload(ftrace.evlist, &ftrace.target,
1665 					       argv, false,
1666 					       ftrace__workload_exec_failed_signal);
1667 		if (ret < 0)
1668 			goto out_delete_evlist;
1669 	}
1670 
1671 	ret = cmd_func(&ftrace);
1672 
1673 out_delete_evlist:
1674 	evlist__delete(ftrace.evlist);
1675 
1676 out_delete_filters:
1677 	delete_filter_func(&ftrace.filters);
1678 	delete_filter_func(&ftrace.notrace);
1679 	delete_filter_func(&ftrace.graph_funcs);
1680 	delete_filter_func(&ftrace.nograph_funcs);
1681 
1682 	return ret;
1683 }
1684