cregit-Linux how code gets into the kernel

Release 4.10 tools/perf/util/trace-event-info.c

Directory: tools/perf/util
/*
 * Copyright (C) 2008,2009, Steven Rostedt <srostedt@redhat.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License (not later!)
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#include "util.h"
#include <dirent.h>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>
#include <linux/list.h>
#include <linux/kernel.h>

#include "../perf.h"
#include "trace-event.h"
#include <api/fs/tracing_path.h>
#include "evsel.h"
#include "debug.h"


#define VERSION "0.5"


static int output_fd;



int bigendian(void) { unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; unsigned int *ptr; ptr = (unsigned int *)(void *)str; return *ptr == 0x01020304; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt5092.59%150.00%
ingo molnaringo molnar47.41%150.00%
Total54100.00%2100.00%

/* unfortunately, you can not stat debugfs or proc files for size */
static int record_file(const char *file, ssize_t hdr_sz) { unsigned long long size = 0; char buf[BUFSIZ], *sizep; off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR); int r, fd; int err = -EIO; fd = open(file, O_RDONLY); if (fd < 0) { pr_debug("Can't read '%s'", file); return -errno; } /* put in zeros for file size, then fill true size later */ if (hdr_sz) { if (write(output_fd, &size, hdr_sz) != hdr_sz) goto out; } do { r = read(fd, buf, BUFSIZ); if (r > 0) { size += r; if (write(output_fd, buf, r) != r) goto out; } } while (r > 0); /* ugh, handle big-endian hdr_size == 4 */ sizep = (char*)&size; if (bigendian()) sizep += sizeof(u64) - hdr_sz; if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) { pr_debug("writing file size failed\n"); goto out; } err = 0; out: close(fd); return err; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt9442.92%120.00%
namhyung kimnamhyung kim6027.40%240.00%
sonny raosonny rao5926.94%120.00%
jiri olsajiri olsa62.74%120.00%
Total219100.00%5100.00%


static int record_header_files(void) { char *path; struct stat st; int err = -EIO; path = get_tracing_file("events/header_page"); if (!path) { pr_debug("can't get tracing/events/header_page"); return -ENOMEM; } if (stat(path, &st) < 0) { pr_debug("can't read '%s'", path); goto out; } if (write(output_fd, "header_page", 12) != 12) { pr_debug("can't write header_page\n"); goto out; } if (record_file(path, 8) < 0) { pr_debug("can't record header_page file\n"); goto out; } put_tracing_file(path); path = get_tracing_file("events/header_event"); if (!path) { pr_debug("can't get tracing/events/header_event"); err = -ENOMEM; goto out; } if (stat(path, &st) < 0) { pr_debug("can't read '%s'", path); goto out; } if (write(output_fd, "header_event", 13) != 13) { pr_debug("can't write header_event\n"); goto out; } if (record_file(path, 8) < 0) { pr_debug("can't record header_event file\n"); goto out; } err = 0; out: put_tracing_file(path); return err; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim12755.95%466.67%
steven rostedtsteven rostedt8336.56%116.67%
sonny raosonny rao177.49%116.67%
Total227100.00%6100.00%


static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) { while (tps) { if (!strcmp(sys, tps->name)) return true; tps = tps->next; } return false; }

Contributors

PersonTokensPropCommitsCommitProp
frederic weisbeckerfrederic weisbecker45100.00%1100.00%
Total45100.00%1100.00%


static int copy_event_system(const char *sys, struct tracepoint_path *tps) { struct dirent *dent; struct stat st; char *format; DIR *dir; int count = 0; int ret; int err; dir = opendir(sys); if (!dir) { pr_debug("can't read directory '%s'", sys); return -errno; } while ((dent = readdir(dir))) { if (dent->d_type != DT_DIR || strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0 || !name_in_tp_list(dent->d_name, tps)) continue; if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) { err = -ENOMEM; goto out; } ret = stat(format, &st); free(format); if (ret < 0) continue; count++; } if (write(output_fd, &count, 4) != 4) { err = -EIO; pr_debug("can't write count\n"); goto out; } rewinddir(dir); while ((dent = readdir(dir))) { if (dent->d_type != DT_DIR || strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0 || !name_in_tp_list(dent->d_name, tps)) continue; if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) { err = -ENOMEM; goto out; } ret = stat(format, &st); if (ret >= 0) { err = record_file(format, 8); if (err) { free(format); goto out; } } free(format); } err = 0; out: closedir(dir); return err; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt20558.24%111.11%
namhyung kimnamhyung kim8223.30%333.33%
frederic weisbeckerfrederic weisbecker257.10%111.11%
andy shevchenkoandy shevchenko226.25%111.11%
ulrich drepperulrich drepper123.41%111.11%
xiao guangrongxiao guangrong51.42%111.11%
sonny raosonny rao10.28%111.11%
Total352100.00%9100.00%


static int record_ftrace_files(struct tracepoint_path *tps) { char *path; int ret; path = get_tracing_file("events/ftrace"); if (!path) { pr_debug("can't get tracing/events/ftrace"); return -ENOMEM; } ret = copy_event_system(path, tps); put_tracing_file(path); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt2644.83%116.67%
namhyung kimnamhyung kim2644.83%466.67%
frederic weisbeckerfrederic weisbecker610.34%116.67%
Total58100.00%6100.00%


static bool system_in_tp_list(char *sys, struct tracepoint_path *tps) { while (tps) { if (!strcmp(sys, tps->system)) return true; tps = tps->next; } return false; }

Contributors

PersonTokensPropCommitsCommitProp
frederic weisbeckerfrederic weisbecker45100.00%1100.00%
Total45100.00%1100.00%


static int record_event_files(struct tracepoint_path *tps) { struct dirent *dent; struct stat st; char *path; char *sys; DIR *dir; int count = 0; int ret; int err; path = get_tracing_file("events"); if (!path) { pr_debug("can't get tracing/events"); return -ENOMEM; } dir = opendir(path); if (!dir) { err = -errno; pr_debug("can't read directory '%s'", path); goto out; } while ((dent = readdir(dir))) { if (dent->d_type != DT_DIR || strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0 || strcmp(dent->d_name, "ftrace") == 0 || !system_in_tp_list(dent->d_name, tps)) continue; count++; } if (write(output_fd, &count, 4) != 4) { err = -EIO; pr_debug("can't write count\n"); goto out; } rewinddir(dir); while ((dent = readdir(dir))) { if (dent->d_type != DT_DIR || strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0 || strcmp(dent->d_name, "ftrace") == 0 || !system_in_tp_list(dent->d_name, tps)) continue; if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) { err = -ENOMEM; goto out; } ret = stat(sys, &st); if (ret >= 0) { ssize_t size = strlen(dent->d_name) + 1; if (write(output_fd, dent->d_name, size) != size || copy_event_system(sys, tps) < 0) { err = -EIO; free(sys); goto out; } } free(sys); } err = 0; out: closedir(dir); put_tracing_file(path); return err; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt22057.44%110.00%
namhyung kimnamhyung kim10928.46%550.00%
frederic weisbeckerfrederic weisbecker266.79%110.00%
ulrich drepperulrich drepper123.13%110.00%
andy shevchenkoandy shevchenko112.87%110.00%
xiao guangrongxiao guangrong51.31%110.00%
Total383100.00%10100.00%


static int record_proc_kallsyms(void) { unsigned long long size = 0; /* * Just to keep older perf.data file parsers happy, record a zero * sized kallsyms file, i.e. do the same thing that was done when * /proc/kallsyms (or something specified via --kallsyms, in a * different path) couldn't be read. */ return write(output_fd, &size, 4) != 4 ? -EIO : 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt1544.12%125.00%
namhyung kimnamhyung kim1235.29%250.00%
arnaldo carvalho de meloarnaldo carvalho de melo720.59%125.00%
Total34100.00%4100.00%


static int record_ftrace_printk(void) { unsigned int size; char *path; struct stat st; int ret, err = 0; path = get_tracing_file("printk_formats"); if (!path) { pr_debug("can't get tracing/printk_formats"); return -ENOMEM; } ret = stat(path, &st); if (ret < 0) { /* not found */ size = 0; if (write(output_fd, &size, 4) != 4) err = -EIO; goto out; } err = record_file(path, 4); out: put_tracing_file(path); return err; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt6456.14%114.29%
namhyung kimnamhyung kim3934.21%457.14%
li zefanli zefan108.77%114.29%
sonny raosonny rao10.88%114.29%
Total114100.00%7100.00%


static void put_tracepoints_path(struct tracepoint_path *tps) { while (tps) { struct tracepoint_path *t = tps; tps = tps->next; zfree(&t->name); zfree(&t->system); free(t); } }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim4690.20%133.33%
arnaldo carvalho de meloarnaldo carvalho de melo47.84%133.33%
frederic weisbeckerfrederic weisbecker11.96%133.33%
Total51100.00%3100.00%


static struct tracepoint_path * get_tracepoints_path(struct list_head *pattrs) { struct tracepoint_path path, *ppath = &path; struct perf_evsel *pos; int nr_tracepoints = 0; list_for_each_entry(pos, pattrs, node) { if (pos->attr.type != PERF_TYPE_TRACEPOINT) continue; ++nr_tracepoints; if (pos->name) { ppath->next = tracepoint_name_to_path(pos->name); if (ppath->next) goto next; if (strchr(pos->name, ':') == NULL) goto try_id; goto error; } try_id: ppath->next = tracepoint_id_to_path(pos->attr.config); if (!ppath->next) { error: pr_debug("No memory to alloc tracepoints list\n"); put_tracepoints_path(&path); return NULL; } next: ppath = ppath->next; } return nr_tracepoints > 0 ? path.next : NULL; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim6741.10%240.00%
frederic weisbeckerfrederic weisbecker6439.26%120.00%
arnaldo carvalho de meloarnaldo carvalho de melo3219.63%240.00%
Total163100.00%5100.00%


bool have_tracepoints(struct list_head *pattrs) { struct perf_evsel *pos; list_for_each_entry(pos, pattrs, node) if (pos->attr.type == PERF_TYPE_TRACEPOINT) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
tom zanussitom zanussi2358.97%266.67%
arnaldo carvalho de meloarnaldo carvalho de melo1641.03%133.33%
Total39100.00%3100.00%


static int tracing_data_header(void) { char buf[20]; ssize_t size; /* just guessing this is someone's birthday.. ;) */ buf[0] = 23; buf[1] = 8; buf[2] = 68; memcpy(buf + 3, "tracing", 7); if (write(output_fd, buf, 10) != 10) return -1; size = strlen(VERSION) + 1; if (write(output_fd, VERSION, size) != size) return -1; /* save endian */ if (bigendian()) buf[0] = 1; else buf[0] = 0; if (write(output_fd, buf, 1) != 1) return -1; /* save size of long */ buf[0] = sizeof(long); if (write(output_fd, buf, 1) != 1) return -1; /* save page_size */ if (write(output_fd, &page_size, 4) != 4) return -1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt10155.80%133.33%
namhyung kimnamhyung kim7440.88%133.33%
jiri olsajiri olsa63.31%133.33%
Total181100.00%3100.00%


struct tracing_data *tracing_data_get(struct list_head *pattrs, int fd, bool temp) { struct tracepoint_path *tps; struct tracing_data *tdata; int err; output_fd = fd; tps = get_tracepoints_path(pattrs); if (!tps) return NULL; tdata = malloc(sizeof(*tdata)); if (!tdata) return NULL; tdata->temp = temp; tdata->size = 0; if (temp) { int temp_fd; snprintf(tdata->temp_file, sizeof(tdata->temp_file), "/tmp/perf-XXXXXX"); if (!mkstemp(tdata->temp_file)) { pr_debug("Can't make temp file"); return NULL; } temp_fd = open(tdata->temp_file, O_RDWR); if (temp_fd < 0) { pr_debug("Can't read '%s'", tdata->temp_file); return NULL; } /* * Set the temp file the default output, so all the * tracing data are stored into it. */ output_fd = temp_fd; } err = tracing_data_header(); if (err) goto out; err = record_header_files(); if (err) goto out; err = record_ftrace_files(tps); if (err) goto out; err = record_event_files(tps); if (err) goto out; err = record_proc_kallsyms(); if (err) goto out; err = record_ftrace_printk(); out: /* * All tracing data are stored by now, we can restore * the default output file in case we used temp file. */ if (temp) { tdata->size = lseek(output_fd, 0, SEEK_CUR); close(output_fd); output_fd = fd; } if (err) zfree(&tdata); put_tracepoints_path(tps); return tdata; }

Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa17562.50%111.11%
namhyung kimnamhyung kim8630.71%444.44%
steven rostedtsteven rostedt93.21%111.11%
frederic weisbeckerfrederic weisbecker62.14%111.11%
arnaldo carvalho de meloarnaldo carvalho de melo41.43%222.22%
Total280100.00%9100.00%


int tracing_data_put(struct tracing_data *tdata) { int err = 0; if (tdata->temp) { err = record_file(tdata->temp_file, 0); unlink(tdata->temp_file); } free(tdata); return err; }

Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa3877.55%150.00%
namhyung kimnamhyung kim1122.45%150.00%
Total49100.00%2100.00%


int read_tracing_data(int fd, struct list_head *pattrs) { int err; struct tracing_data *tdata; /* * We work over the real file, so we can write data * directly, no temp file is needed. */ tdata = tracing_data_get(pattrs, fd, false); if (!tdata) return -ENOMEM; err = tracing_data_put(tdata); return err; }

Contributors

PersonTokensPropCommitsCommitProp
tom zanussitom zanussi2446.15%125.00%
jiri olsajiri olsa2140.38%125.00%
namhyung kimnamhyung kim611.54%125.00%
arnaldo carvalho de meloarnaldo carvalho de melo11.92%125.00%
Total52100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt91537.78%13.70%
namhyung kimnamhyung kim74530.76%622.22%
jiri olsajiri olsa25010.32%311.11%
frederic weisbeckerfrederic weisbecker2249.25%13.70%
sonny raosonny rao793.26%13.70%
arnaldo carvalho de meloarnaldo carvalho de melo763.14%622.22%
tom zanussitom zanussi471.94%311.11%
andy shevchenkoandy shevchenko331.36%13.70%
ulrich drepperulrich drepper271.11%13.70%
xiao guangrongxiao guangrong120.50%27.41%
li zefanli zefan100.41%13.70%
ingo molnaringo molnar40.17%13.70%
Total2422100.00%27100.00%
Directory: tools/perf/util
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.