cregit-Linux how code gets into the kernel

Release 4.11 tools/perf/builtin-ftrace.c

Directory: tools/perf
/*
 * builtin-ftrace.c
 *
 * Copyright (c) 2013  LG Electronics,  Namhyung Kim <namhyung@kernel.org>
 *
 * Released under the GPL v2.
 */

#include "builtin.h"
#include "perf.h"

#include <unistd.h>
#include <signal.h>

#include "debug.h"
#include <subcmd/parse-options.h>
#include "evlist.h"
#include "target.h"
#include "thread_map.h"
#include "util/config.h"



#define DEFAULT_TRACER  "function_graph"


struct perf_ftrace {
	
struct perf_evlist *evlist;
	
struct target target;
	
const char *tracer;
};


static bool done;


static void sig_handler(int sig __maybe_unused) { done = true; }

Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim14100.00%1100.00%
Total14100.00%1100.00%

/* * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since * we asked by setting its exec_error to the function below, * ftrace__workload_exec_failed_signal. * * XXX We need to handle this more appropriately, emitting an error, etc. */
static void ftrace__workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info __maybe_unused, void *ucontext __maybe_unused) { /* workload_exec_errno = info->si_value.sival_int; */ done = true; }

Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim25100.00%1100.00%
Total25100.00%1100.00%


static int write_tracing_file(const char *name, const char *val) { char *file; int fd, ret = -1; ssize_t size = strlen(val); file = get_tracing_file(name); if (!file) { pr_debug("cannot get tracing file: %s\n", name); return -1; } fd = open(file, O_WRONLY); if (fd < 0) { pr_debug("cannot open tracing file: %s\n", name); goto out; } if (write(fd, val, size) == size) ret = 0; else pr_debug("write '%s' to tracing/%s failed\n", val, name); close(fd); out: put_tracing_file(file); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim130100.00%1100.00%
Total130100.00%1100.00%


static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) { if (write_tracing_file("tracing_on", "0") < 0) return -1; if (write_tracing_file("current_tracer", "nop") < 0) return -1; if (write_tracing_file("set_ftrace_pid", " ") < 0) return -1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim60100.00%1100.00%
Total60100.00%1100.00%


static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) { char *trace_file; int trace_fd; char *trace_pid; char buf[4096]; struct pollfd pollfd = { .events = POLLIN, }; if (geteuid() != 0) { pr_err("ftrace only works for root!\n"); return -1; } if (argc < 1) return -1; signal(SIGINT, sig_handler); signal(SIGUSR1, sig_handler); signal(SIGCHLD, sig_handler); reset_tracing_files(ftrace); /* reset ftrace buffer */ if (write_tracing_file("trace", "0") < 0) goto out; if (perf_evlist__prepare_workload(ftrace->evlist, &ftrace->target, argv, false, ftrace__workload_exec_failed_signal) < 0) goto out; if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { pr_err("failed to set current_tracer to %s\n", ftrace->tracer); goto out; } if (asprintf(&trace_pid, "%d", thread_map__pid(ftrace->evlist->threads, 0)) < 0) { pr_err("failed to allocate pid string\n"); goto out; } if (write_tracing_file("set_ftrace_pid", trace_pid) < 0) { pr_err("failed to set pid: %s\n", trace_pid); goto out_free_pid; } trace_file = get_tracing_file("trace_pipe"); if (!trace_file) { pr_err("failed to open trace_pipe\n"); goto out_free_pid; } trace_fd = open(trace_file, O_RDONLY); put_tracing_file(trace_file); if (trace_fd < 0) { pr_err("failed to open trace_pipe\n"); goto out_free_pid; } fcntl(trace_fd, F_SETFL, O_NONBLOCK); pollfd.fd = trace_fd; if (write_tracing_file("tracing_on", "1") < 0) { pr_err("can't enable tracing\n"); goto out_close_fd; } perf_evlist__start_workload(ftrace->evlist); while (!done) { if (poll(&pollfd, 1, -1) < 0) break; if (pollfd.revents & POLLIN) { int n = read(trace_fd, buf, sizeof(buf)); if (n < 0) break; if (fwrite(buf, n, 1, stdout) != 1) break; } } write_tracing_file("tracing_on", "0"); /* read remaining buffer contents */ while (true) { int n = read(trace_fd, buf, sizeof(buf)); if (n <= 0) break; if (fwrite(buf, n, 1, stdout) != 1) break; } out_close_fd: close(trace_fd); out_free_pid: free(trace_pid); out: reset_tracing_files(ftrace); return done ? 0 : -1; }

Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim472100.00%1100.00%
Total472100.00%1100.00%


static int perf_ftrace_config(const char *var, const char *value, void *cb) { struct perf_ftrace *ftrace = cb; if (prefixcmp(var, "ftrace.")) return 0; if (strcmp(var, "ftrace.tracer")) return -1; if (!strcmp(value, "function_graph") || !strcmp(value, "function")) { ftrace->tracer = value; return 0; } pr_err("Please select \"function_graph\" (default) or \"function\"\n"); return -1; }

Contributors

PersonTokensPropCommitsCommitProp
Taeung Song90100.00%1100.00%
Total90100.00%1100.00%


int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) { int ret; struct perf_ftrace ftrace = { .tracer = DEFAULT_TRACER, .target = { .uid = UINT_MAX, }, }; const char * const ftrace_usage[] = { "perf ftrace [<options>] <command>", "perf ftrace [<options>] -- <command> [<options>]", NULL }; const struct option ftrace_options[] = { OPT_STRING('t', "tracer", &ftrace.tracer, "tracer", "tracer to use: function_graph(default) or function"), OPT_INCR('v', "verbose", &verbose, "be more verbose"), OPT_END() }; ret = perf_config(perf_ftrace_config, &ftrace); if (ret < 0) return -1; argc = parse_options(argc, argv, ftrace_options, ftrace_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (!argc) usage_with_options(ftrace_usage, ftrace_options); ftrace.evlist = perf_evlist__new(); if (ftrace.evlist == NULL) return -ENOMEM; ret = perf_evlist__create_maps(ftrace.evlist, &ftrace.target); if (ret < 0) goto out_delete_evlist; ret = __cmd_ftrace(&ftrace, argc, argv); out_delete_evlist: perf_evlist__delete(ftrace.evlist); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim18587.68%125.00%
Taeung Song219.95%250.00%
Arnaldo Carvalho de Melo52.37%125.00%
Total211100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Namhyung Kim94288.78%125.00%
Taeung Song11410.74%250.00%
Arnaldo Carvalho de Melo50.47%125.00%
Total1061100.00%4100.00%
Directory: tools/perf
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.