From 77e0070da41f76e1ebd15291fb0254b0c174adfa Mon Sep 17 00:00:00 2001 From: Mark Drayton Date: Wed, 26 Aug 2015 12:18:15 -0700 Subject: perf script: Add --[no-]-demangle/--[no-]-demangle-kernel Sometimes when post-processing output from `perf script` one does not want to demangle C++ symbol names. Add an option to allow this. Also add --[no-]demangle-kernel to be consistent with top/report/probe. Signed-off-by: Mark Drayton Cc: Andi Kleen Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1440616695-32340-1-git-send-email-scientist@fb.com Signed-off-by: Yannick Brosseau Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 7 +++++++ tools/perf/builtin-script.c | 5 +++++ 2 files changed, 12 insertions(+) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index c0d24791a7f3..614b2c7b0293 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -226,6 +226,13 @@ OPTIONS Display context switch events i.e. events of type PERF_RECORD_SWITCH or PERF_RECORD_SWITCH_CPU_WIDE. +--demangle:: + Demangle symbol names to human readable form. It's enabled by default, + disable with --no-demangle. + +--demangle-kernel:: + Demangle kernel symbol names to human readable form (for C++ kernels). + --header Show perf.data header. diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 105332e950a9..4430340292c0 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1671,6 +1671,11 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) itrace_parse_synth_opts), OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, "Show full source file name path for source lines"), + OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, + "Enable symbol demangling"), + OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, + "Enable kernel symbol demangling"), + OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL }; -- cgit v1.2.1 From 1d945012d1381f0232ea2d66e32b06182eedb476 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 27 Aug 2015 09:46:01 -0400 Subject: tools lib traceeveent: Allow for negative numbers in print format It was reported that "%-8s" does not parse well when used in the printk format. The '-' is what is throwing it off. Allow that to be included. Reporter note: Example before: transhuge-stres-10730 [004] 5897.713989: mm_compaction_finished: node=0 zone=>-<8s order=-2119871790 ret= Example after: transhuge-stres-4235 [000] 453.149280: mm_compaction_finished: node=0 zone=ffffffff81815d7a order=9 ret= (I will send patches to fix the string handling in the tracepoints so it's on par with in-kernel printing via trace_pipe:) transhuge-stres-10921 [007] ...1 6307.140205: mm_compaction_finished: node=0 zone=Normal order=9 ret=partial Reported-by: Vlastimil Babka Signed-off-by: Steven Rostedt Tested-by: Vlastimil Babka Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20150827094601.46518bcc@gandalf.local.home Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 5c1867a13ef2..4d885934b919 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -4828,6 +4828,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event case 'z': case 'Z': case '0' ... '9': + case '-': goto cont_process; case 'p': if (pevent->long_size == 4) -- cgit v1.2.1 From 84e5d89a777cca26cc513264752b439874702dd6 Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Mon, 17 Aug 2015 12:48:52 -0700 Subject: perf scripts python: Add new compaction-times script This patch creates a new script (compaction-times) to report time spent in mm compaction. It is possible to report times in nanoseconds (default) or microseconds (-u). The option -p will break down results by process id, -pv will further decompose by each compaction entry/exit. For each compaction entry/exit what is reported is controlled by the options: -t report only timing -m report migration stats -ms report migration scanner stats -fs report free scanner stats The default is to report all. Entries may be further filtered by pid, pid-range or comm (regex). The script is useful when analysing workloads that compact memory. The most common example will be THP allocations on systems with a lot of uptime that has fragmented memory. This is an example of using the script to analyse a thpscale from mmtests which deliberately fragments memory and allocates THP in 4 separate threads # Recording step, one of the following; $ perf record -e 'compaction:mm_compaction_*' ./workload # or: $ perf script record compaction-times # Reporting: basic total: 2444505743ns migration: moved=357738 failed=39275 free_scanner: scanned=2705578 isolated=387875 migration_scanner: scanned=414426 isolated=397013 # Reporting: Per task stall times $ perf script report compaction-times -- -t -p total: 2444505743ns 6384[thpscale]: 740800017ns 6385[thpscale]: 274119512ns 6386[thpscale]: 832961337ns 6383[thpscale]: 596624877ns # Reporting: Per-compaction attempts for task 6385 $ perf script report compaction-times -- -m -pv 6385 total: 274119512ns migration: moved=14893 failed=24285 6385[thpscale]: 274119512ns migration: moved=14893 failed=24285 6385[thpscale].1: 3033277ns migration: moved=511 failed=1 6385[thpscale].2: 9592094ns migration: moved=1524 failed=12 6385[thpscale].3: 2495587ns migration: moved=512 failed=0 6385[thpscale].4: 2561766ns migration: moved=512 failed=0 6385[thpscale].5: 2523521ns migration: moved=512 failed=0 ..... output continues ... Changes since v1: - report stats for isolate_migratepages and isolate_freepages (Vlastimil Babka) - refactor code to achieve above - add help text - output to stdout/stderr explicitly Signed-off-by: Tony Jones Cc: Mel Gorman Cc: Vlastimil Babka Link: http://lkml.kernel.org/r/1439840932-8933-1-git-send-email-tonyj@suse.com Signed-off-by: Arnaldo Carvalho de Melo --- .../scripts/python/bin/compaction-times-record | 2 + .../scripts/python/bin/compaction-times-report | 4 + tools/perf/scripts/python/compaction-times.py | 311 +++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 tools/perf/scripts/python/bin/compaction-times-record create mode 100644 tools/perf/scripts/python/bin/compaction-times-report create mode 100644 tools/perf/scripts/python/compaction-times.py (limited to 'tools') diff --git a/tools/perf/scripts/python/bin/compaction-times-record b/tools/perf/scripts/python/bin/compaction-times-record new file mode 100644 index 000000000000..6edcd40e14e8 --- /dev/null +++ b/tools/perf/scripts/python/bin/compaction-times-record @@ -0,0 +1,2 @@ +#!/bin/bash +perf record -e compaction:mm_compaction_begin -e compaction:mm_compaction_end -e compaction:mm_compaction_migratepages -e compaction:mm_compaction_isolate_migratepages -e compaction:mm_compaction_isolate_freepages $@ diff --git a/tools/perf/scripts/python/bin/compaction-times-report b/tools/perf/scripts/python/bin/compaction-times-report new file mode 100644 index 000000000000..3dc13897cfde --- /dev/null +++ b/tools/perf/scripts/python/bin/compaction-times-report @@ -0,0 +1,4 @@ +#!/bin/bash +#description: display time taken by mm compaction +#args: [-h] [-u] [-p|-pv] [-t | [-m] [-fs] [-ms]] [pid|pid-range|comm-regex] +perf script -s "$PERF_EXEC_PATH"/scripts/python/compaction-times.py $@ diff --git a/tools/perf/scripts/python/compaction-times.py b/tools/perf/scripts/python/compaction-times.py new file mode 100644 index 000000000000..239cb0568ec3 --- /dev/null +++ b/tools/perf/scripts/python/compaction-times.py @@ -0,0 +1,311 @@ +# report time spent in compaction +# Licensed under the terms of the GNU GPL License version 2 + +# testing: +# 'echo 1 > /proc/sys/vm/compact_memory' to force compaction of all zones + +import os +import sys +import re + +import signal +signal.signal(signal.SIGPIPE, signal.SIG_DFL) + +usage = "usage: perf script report compaction-times.py -- [-h] [-u] [-p|-pv] [-t | [-m] [-fs] [-ms]] [pid|pid-range|comm-regex]\n" + +class popt: + DISP_DFL = 0 + DISP_PROC = 1 + DISP_PROC_VERBOSE=2 + +class topt: + DISP_TIME = 0 + DISP_MIG = 1 + DISP_ISOLFREE = 2 + DISP_ISOLMIG = 4 + DISP_ALL = 7 + +class comm_filter: + def __init__(self, re): + self.re = re + + def filter(self, pid, comm): + m = self.re.search(comm) + return m == None or m.group() == "" + +class pid_filter: + def __init__(self, low, high): + self.low = (0 if low == "" else int(low)) + self.high = (0 if high == "" else int(high)) + + def filter(self, pid, comm): + return not (pid >= self.low and (self.high == 0 or pid <= self.high)) + +def set_type(t): + global opt_disp + opt_disp = (t if opt_disp == topt.DISP_ALL else opt_disp|t) + +def ns(sec, nsec): + return (sec * 1000000000) + nsec + +def time(ns): + return "%dns" % ns if opt_ns else "%dus" % (round(ns, -3) / 1000) + +class pair: + def __init__(self, aval, bval, alabel = None, blabel = None): + self.alabel = alabel + self.blabel = blabel + self.aval = aval + self.bval = bval + + def __add__(self, rhs): + self.aval += rhs.aval + self.bval += rhs.bval + return self + + def __str__(self): + return "%s=%d %s=%d" % (self.alabel, self.aval, self.blabel, self.bval) + +class cnode: + def __init__(self, ns): + self.ns = ns + self.migrated = pair(0, 0, "moved", "failed") + self.fscan = pair(0,0, "scanned", "isolated") + self.mscan = pair(0,0, "scanned", "isolated") + + def __add__(self, rhs): + self.ns += rhs.ns + self.migrated += rhs.migrated + self.fscan += rhs.fscan + self.mscan += rhs.mscan + return self + + def __str__(self): + prev = 0 + s = "%s " % time(self.ns) + if (opt_disp & topt.DISP_MIG): + s += "migration: %s" % self.migrated + prev = 1 + if (opt_disp & topt.DISP_ISOLFREE): + s += "%sfree_scanner: %s" % (" " if prev else "", self.fscan) + prev = 1 + if (opt_disp & topt.DISP_ISOLMIG): + s += "%smigration_scanner: %s" % (" " if prev else "", self.mscan) + return s + + def complete(self, secs, nsecs): + self.ns = ns(secs, nsecs) - self.ns + + def increment(self, migrated, fscan, mscan): + if (migrated != None): + self.migrated += migrated + if (fscan != None): + self.fscan += fscan + if (mscan != None): + self.mscan += mscan + + +class chead: + heads = {} + val = cnode(0); + fobj = None + + @classmethod + def add_filter(cls, filter): + cls.fobj = filter + + @classmethod + def create_pending(cls, pid, comm, start_secs, start_nsecs): + filtered = 0 + try: + head = cls.heads[pid] + filtered = head.is_filtered() + except KeyError: + if cls.fobj != None: + filtered = cls.fobj.filter(pid, comm) + head = cls.heads[pid] = chead(comm, pid, filtered) + + if not filtered: + head.mark_pending(start_secs, start_nsecs) + + @classmethod + def increment_pending(cls, pid, migrated, fscan, mscan): + head = cls.heads[pid] + if not head.is_filtered(): + if head.is_pending(): + head.do_increment(migrated, fscan, mscan) + else: + sys.stderr.write("missing start compaction event for pid %d\n" % pid) + + @classmethod + def complete_pending(cls, pid, secs, nsecs): + head = cls.heads[pid] + if not head.is_filtered(): + if head.is_pending(): + head.make_complete(secs, nsecs) + else: + sys.stderr.write("missing start compaction event for pid %d\n" % pid) + + @classmethod + def gen(cls): + if opt_proc != popt.DISP_DFL: + for i in cls.heads: + yield cls.heads[i] + + @classmethod + def str(cls): + return cls.val + + def __init__(self, comm, pid, filtered): + self.comm = comm + self.pid = pid + self.val = cnode(0) + self.pending = None + self.filtered = filtered + self.list = [] + + def __add__(self, rhs): + self.ns += rhs.ns + self.val += rhs.val + return self + + def mark_pending(self, secs, nsecs): + self.pending = cnode(ns(secs, nsecs)) + + def do_increment(self, migrated, fscan, mscan): + self.pending.increment(migrated, fscan, mscan) + + def make_complete(self, secs, nsecs): + self.pending.complete(secs, nsecs) + chead.val += self.pending + + if opt_proc != popt.DISP_DFL: + self.val += self.pending + + if opt_proc == popt.DISP_PROC_VERBOSE: + self.list.append(self.pending) + self.pending = None + + def enumerate(self): + if opt_proc == popt.DISP_PROC_VERBOSE and not self.is_filtered(): + for i, pelem in enumerate(self.list): + sys.stdout.write("%d[%s].%d: %s\n" % (self.pid, self.comm, i+1, pelem)) + + def is_pending(self): + return self.pending != None + + def is_filtered(self): + return self.filtered + + def display(self): + if not self.is_filtered(): + sys.stdout.write("%d[%s]: %s\n" % (self.pid, self.comm, self.val)) + + +def trace_end(): + sys.stdout.write("total: %s\n" % chead.str()) + for i in chead.gen(): + i.display(), + i.enumerate() + +def compaction__mm_compaction_migratepages(event_name, context, common_cpu, + common_secs, common_nsecs, common_pid, common_comm, + common_callchain, nr_migrated, nr_failed): + + chead.increment_pending(common_pid, + pair(nr_migrated, nr_failed), None, None) + +def compaction__mm_compaction_isolate_freepages(event_name, context, common_cpu, + common_secs, common_nsecs, common_pid, common_comm, + common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): + + chead.increment_pending(common_pid, + None, pair(nr_scanned, nr_taken), None) + +def compaction__mm_compaction_isolate_migratepages(event_name, context, common_cpu, + common_secs, common_nsecs, common_pid, common_comm, + common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): + + chead.increment_pending(common_pid, + None, None, pair(nr_scanned, nr_taken)) + +def compaction__mm_compaction_end(event_name, context, common_cpu, + common_secs, common_nsecs, common_pid, common_comm, + common_callchain, zone_start, migrate_start, free_start, zone_end, + sync, status): + + chead.complete_pending(common_pid, common_secs, common_nsecs) + +def compaction__mm_compaction_begin(event_name, context, common_cpu, + common_secs, common_nsecs, common_pid, common_comm, + common_callchain, zone_start, migrate_start, free_start, zone_end, + sync): + + chead.create_pending(common_pid, common_comm, common_secs, common_nsecs) + +def pr_help(): + global usage + + sys.stdout.write(usage) + sys.stdout.write("\n") + sys.stdout.write("-h display this help\n") + sys.stdout.write("-p display by process\n") + sys.stdout.write("-pv display by process (verbose)\n") + sys.stdout.write("-t display stall times only\n") + sys.stdout.write("-m display stats for migration\n") + sys.stdout.write("-fs display stats for free scanner\n") + sys.stdout.write("-ms display stats for migration scanner\n") + sys.stdout.write("-u display results in microseconds (default nanoseconds)\n") + + +comm_re = None +pid_re = None +pid_regex = "^(\d*)-(\d*)$|^(\d*)$" + +opt_proc = popt.DISP_DFL +opt_disp = topt.DISP_ALL + +opt_ns = True + +argc = len(sys.argv) - 1 +if argc >= 1: + pid_re = re.compile(pid_regex) + + for i, opt in enumerate(sys.argv[1:]): + if opt[0] == "-": + if opt == "-h": + pr_help() + exit(0); + elif opt == "-p": + opt_proc = popt.DISP_PROC + elif opt == "-pv": + opt_proc = popt.DISP_PROC_VERBOSE + elif opt == '-u': + opt_ns = False + elif opt == "-t": + set_type(topt.DISP_TIME) + elif opt == "-m": + set_type(topt.DISP_MIG) + elif opt == "-fs": + set_type(topt.DISP_ISOLFREE) + elif opt == "-ms": + set_type(topt.DISP_ISOLMIG) + else: + sys.exit(usage) + + elif i == argc - 1: + m = pid_re.search(opt) + if m != None and m.group() != "": + if m.group(3) != None: + f = pid_filter(m.group(3), m.group(3)) + else: + f = pid_filter(m.group(1), m.group(2)) + else: + try: + comm_re=re.compile(opt) + except: + sys.stderr.write("invalid regex '%s'" % opt) + sys.exit(usage) + f = comm_filter(comm_re) + + chead.add_filter(f) -- cgit v1.2.1 From a598bb5e3558509cbb8aa1d422071ef61fda9d77 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 28 Aug 2015 12:02:37 -0300 Subject: perf trace: Add header with copyright and background info Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-5yqtfs728r1j1u8zmg8ufxwm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2f1162daa3c5..4e3abba03062 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1,3 +1,21 @@ +/* + * builtin-trace.c + * + * Builtin 'trace' command: + * + * Display a continuously updated trace of any workload, CPU, specific PID, + * system wide, etc. Default format is loosely strace like, but any other + * event may be specified using --event. + * + * Copyright (C) 2012, 2013, 2014, 2015 Red Hat Inc, Arnaldo Carvalho de Melo + * + * Initially based on the 'trace' prototype by Thomas Gleixner: + * + * http://lwn.net/Articles/415728/ ("Announcing a new utility: 'trace'") + * + * Released under the GPL v2. (and only v2, not any later version) + */ + #include #include "builtin.h" #include "util/color.h" @@ -27,6 +45,7 @@ #ifndef MADV_HWPOISON # define MADV_HWPOISON 100 + #endif #ifndef MADV_MERGEABLE -- cgit v1.2.1 From d49e4695077278ee3016cd242967de23072ec331 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Aug 2015 08:07:40 -0400 Subject: perf evsel: Add a backpointer to the evlist a evsel is in So that functions that deal primarily with an evsel to access information that concerns the whole evlist it is in. Cc: Adrian Hunter Cc: Andi Kleen Cc: Andy Lutomirski Cc: Jiri Olsa Cc: Kan Liang Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1440677263-21954-5-git-send-email-kan.liang@intel.com Signed-off-by: Kan Liang Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 ++ tools/perf/util/evsel.c | 2 ++ tools/perf/util/evsel.h | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e9a5d432902c..8d00039d6a20 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -98,6 +98,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) evlist__for_each_safe(evlist, n, pos) { list_del_init(&pos->node); + pos->evlist = NULL; perf_evsel__delete(pos); } @@ -125,6 +126,7 @@ void perf_evlist__delete(struct perf_evlist *evlist) void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) { + entry->evlist = evlist; list_add_tail(&entry->node, &evlist->entries); entry->idx = evlist->nr_entries; entry->tracking = !entry->idx; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b096ef7a240c..bac25f41a751 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -206,6 +206,7 @@ void perf_evsel__init(struct perf_evsel *evsel, evsel->leader = evsel; evsel->unit = ""; evsel->scale = 1.0; + evsel->evlist = NULL; INIT_LIST_HEAD(&evsel->node); INIT_LIST_HEAD(&evsel->config_terms); perf_evsel__object.init(evsel); @@ -1026,6 +1027,7 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) void perf_evsel__exit(struct perf_evsel *evsel) { assert(list_empty(&evsel->node)); + assert(evsel->evlist == NULL); perf_evsel__free_fd(evsel); perf_evsel__free_id(evsel); perf_evsel__free_config_terms(evsel); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 93ac6b128149..298e6bbca200 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -60,6 +60,9 @@ struct perf_evsel_config_term { /** struct perf_evsel - event selector * + * @evlist - evlist this evsel is in, if it is in one. + * @node - To insert it into evlist->entries or in other list_heads, say in + * the event parsing routines. * @name - Can be set to retain the original event name passed by the user, * so that when showing results in tools such as 'perf stat', we * show the name used, not some alias. @@ -73,6 +76,7 @@ struct perf_evsel_config_term { */ struct perf_evsel { struct list_head node; + struct perf_evlist *evlist; struct perf_event_attr attr; char *filter; struct xyarray *fd; -- cgit v1.2.1 From 0b5a7935f3b5b7d40293b02c3e552f3d67af208b Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Sat, 15 Aug 2015 20:42:59 +0900 Subject: perf buildid: Introduce sysfs/filename__sprintf_build_id Introduce sysfs/filename__sprintf_build_id for consolidating similar code. Signed-off-by: Masami Hiramatsu Cc: Adrian Hunter Cc: Borislav Petkov Cc: Hemant Kumar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20150815114259.13642.34685.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 14 ++------------ tools/perf/builtin-buildid-list.c | 24 ++++++++++-------------- tools/perf/util/build-id.c | 32 ++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 3 +++ 4 files changed, 47 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 65b4835309c7..7b8450cd33c2 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -25,8 +25,6 @@ static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) { char root_dir[PATH_MAX]; - char notes[PATH_MAX]; - u8 build_id[BUILD_ID_SIZE]; char *p; strlcpy(root_dir, proc_dir, sizeof(root_dir)); @@ -35,15 +33,7 @@ static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) if (!p) return -1; *p = '\0'; - - scnprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir); - - if (sysfs__read_build_id(notes, build_id, sizeof(build_id))) - return -1; - - build_id__sprintf(build_id, sizeof(build_id), sbuildid); - - return 0; + return sysfs__sprintf_build_id(root_dir, sbuildid); } static int build_id_cache__kcore_dir(char *dir, size_t sz) @@ -138,7 +128,7 @@ static int build_id_cache__add_kcore(const char *filename, bool force) return -1; *p = '\0'; - if (build_id_cache__kcore_buildid(from_dir, sbuildid)) + if (build_id_cache__kcore_buildid(from_dir, sbuildid) < 0) return -1; scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s", diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index b5ca988ebfbe..918b4de29de4 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -19,29 +19,25 @@ static int sysfs__fprintf_build_id(FILE *fp) { - u8 kallsyms_build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; + int ret; - if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id, - sizeof(kallsyms_build_id)) != 0) - return -1; + ret = sysfs__sprintf_build_id("/", sbuild_id); + if (ret != sizeof(sbuild_id)) + return ret < 0 ? ret : -EINVAL; - build_id__sprintf(kallsyms_build_id, sizeof(kallsyms_build_id), - sbuild_id); - fprintf(fp, "%s\n", sbuild_id); - return 0; + return fprintf(fp, "%s\n", sbuild_id); } static int filename__fprintf_build_id(const char *name, FILE *fp) { - u8 build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; + int ret; - if (filename__read_build_id(name, build_id, - sizeof(build_id)) != sizeof(build_id)) - return 0; + ret = filename__sprintf_build_id(name, sbuild_id); + if (ret != sizeof(sbuild_id)) + return ret < 0 ? ret : -EINVAL; - build_id__sprintf(build_id, sizeof(build_id), sbuild_id); return fprintf(fp, "%s\n", sbuild_id); } @@ -63,7 +59,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits) /* * See if this is an ELF file first: */ - if (filename__fprintf_build_id(input_name, stdout)) + if (filename__fprintf_build_id(input_name, stdout) > 0) goto out; session = perf_session__new(&file, false, &build_id__mark_dso_hit_ops); diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 4a2c2f0ead41..d909459fb54c 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -93,6 +93,38 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf) return raw - build_id; } +int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id) +{ + char notes[PATH_MAX]; + u8 build_id[BUILD_ID_SIZE]; + int ret; + + if (!root_dir) + root_dir = ""; + + scnprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir); + + ret = sysfs__read_build_id(notes, build_id, sizeof(build_id)); + if (ret < 0) + return ret; + + return build_id__sprintf(build_id, sizeof(build_id), sbuild_id); +} + +int filename__sprintf_build_id(const char *pathname, char *sbuild_id) +{ + u8 build_id[BUILD_ID_SIZE]; + int ret; + + ret = filename__read_build_id(pathname, build_id, sizeof(build_id)); + if (ret < 0) + return ret; + else if (ret != sizeof(build_id)) + return -EINVAL; + + return build_id__sprintf(build_id, sizeof(build_id), sbuild_id); +} + /* asnprintf consolidates asprintf and snprintf */ static int asnprintf(char **strp, size_t size, const char *fmt, ...) { diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index ce2f493f057a..27a14a8a945b 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -12,6 +12,9 @@ extern struct perf_tool build_id__mark_dso_hit_ops; struct dso; int build_id__sprintf(const u8 *build_id, int len, char *bf); +int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id); +int filename__sprintf_build_id(const char *pathname, char *sbuild_id); + char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, -- cgit v1.2.1 From 9f44f0cc1c32f1542071447a9493652bbc03facb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 26 Aug 2015 15:46:44 +0200 Subject: perf tools: Add tracing_path and remove unneeded functions There's no need for find_tracing_dir, because perf already searches for debugfs/tracefs mount on start and populate tracing_events_path. Adding tracing_path to carry tracing dir string to be used in get_tracing_file instead of calling find_tracing_dir. Signed-off-by: Jiri Olsa Cc: Raphael Beamonte Cc: David Ahern Cc: Matt Fleming Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1440596813-12844-3-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/util.c | 56 ++++---------------------------------------------- tools/perf/util/util.h | 2 +- 2 files changed, 5 insertions(+), 53 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index f7adf1203df1..d33c34196a5a 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -34,6 +34,7 @@ bool test_attr__enabled; bool perf_host = true; bool perf_guest = false; +char tracing_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing"; char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; void event_attr_init(struct perf_event_attr *attr) @@ -391,6 +392,8 @@ void set_term_quiet_input(struct termios *old) static void set_tracing_events_path(const char *tracing, const char *mountpoint) { + snprintf(tracing_path, sizeof(tracing_path), "%s/%s", + mountpoint, tracing); snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s", mountpoint, tracing, "events"); } @@ -440,62 +443,11 @@ void perf_debugfs_set_path(const char *mntpt) set_tracing_events_path("tracing/", mntpt); } -static const char *find_tracefs(void) -{ - const char *path = __perf_tracefs_mount(NULL); - - return path; -} - -static const char *find_debugfs(void) -{ - const char *path = __perf_debugfs_mount(NULL); - - if (!path) - fprintf(stderr, "Your kernel does not support the debugfs filesystem"); - - return path; -} - -/* - * Finds the path to the debugfs/tracing - * Allocates the string and stores it. - */ -const char *find_tracing_dir(void) -{ - const char *tracing_dir = ""; - static char *tracing; - static int tracing_found; - const char *debugfs; - - if (tracing_found) - return tracing; - - debugfs = find_tracefs(); - if (!debugfs) { - tracing_dir = "/tracing"; - debugfs = find_debugfs(); - if (!debugfs) - return NULL; - } - - if (asprintf(&tracing, "%s%s", debugfs, tracing_dir) < 0) - return NULL; - - tracing_found = 1; - return tracing; -} - char *get_tracing_file(const char *name) { - const char *tracing; char *file; - tracing = find_tracing_dir(); - if (!tracing) - return NULL; - - if (asprintf(&file, "%s/%s", tracing, name) < 0) + if (asprintf(&file, "%s/%s", tracing_path, name) < 0) return NULL; return file; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 88a891562a47..291be1d84bc3 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -83,10 +83,10 @@ extern const char *graph_line; extern const char *graph_dotted_line; extern char buildid_dir[]; +extern char tracing_path[]; extern char tracing_events_path[]; extern void perf_debugfs_set_path(const char *mountpoint); const char *perf_debugfs_mount(const char *mountpoint); -const char *find_tracing_dir(void); char *get_tracing_file(const char *name); void put_tracing_file(char *file); -- cgit v1.2.1 From 9f30fffc78ca35c862f74f34cc597c7fdddc8793 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 26 Aug 2015 15:46:45 +0200 Subject: perf tools: Do not change lib/api/fs/debugfs directly The tracing_events_path is the variable we want to change via --debugfs-dir option, not the debugfs_mountpoint. Signed-off-by: Jiri Olsa Reviewed-by: Matt Fleming Cc: Raphael Beamonte Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1440596813-12844-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.c | 2 +- tools/perf/util/util.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/perf.c b/tools/perf/perf.c index b857fcbd00cf..07dbff5c0e60 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -231,7 +231,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argc)--; } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); - fprintf(stderr, "dir: %s\n", debugfs_mountpoint); + fprintf(stderr, "dir: %s\n", tracing_path); if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--list-cmds")) { diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index d33c34196a5a..7acafb3c5592 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -439,7 +439,6 @@ const char *perf_debugfs_mount(const char *mountpoint) void perf_debugfs_set_path(const char *mntpt) { - snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt); set_tracing_events_path("tracing/", mntpt); } -- cgit v1.2.1 From ce80d3bef9ff97638ca57a5659ef6ad356f35047 Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Fri, 28 Aug 2015 05:48:04 -0400 Subject: perf tools: Rename perf_session_env to perf_env As it is not necessarily tied to a perf.data file and needs using in places where a perf_session is not required. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Kan Liang Cc: Adrian Hunter Cc: Andi Kleen Cc: Andy Lutomirski Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1440755289-30939-4-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.c | 4 ++-- tools/perf/arch/common.h | 2 +- tools/perf/ui/browser.h | 4 ++-- tools/perf/ui/browsers/header.c | 2 +- tools/perf/ui/browsers/hists.c | 12 ++++++------ tools/perf/util/header.h | 4 ++-- tools/perf/util/hist.h | 4 ++-- tools/perf/util/session.c | 2 +- tools/perf/util/symbol.c | 4 ++-- tools/perf/util/symbol.h | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index b7bb42c44694..b00dfd92ea73 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -128,7 +128,7 @@ static const char *normalize_arch(char *arch) return arch; } -static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, +static int perf_session_env__lookup_binutils_path(struct perf_env *env, const char *name, const char **path) { @@ -206,7 +206,7 @@ out_error: return -1; } -int perf_session_env__lookup_objdump(struct perf_session_env *env) +int perf_session_env__lookup_objdump(struct perf_env *env) { /* * For live mode, env->arch will be NULL and we can use diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h index ede246eda9be..20176df69fc8 100644 --- a/tools/perf/arch/common.h +++ b/tools/perf/arch/common.h @@ -5,6 +5,6 @@ extern const char *objdump_path; -int perf_session_env__lookup_objdump(struct perf_session_env *env); +int perf_session_env__lookup_objdump(struct perf_env *env); #endif /* ARCH_PERF_COMMON_H */ diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index 52be87125def..f3cef564de02 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -61,8 +61,8 @@ int ui_browser__help_window(struct ui_browser *browser, const char *text); bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); int ui_browser__input_window(const char *title, const char *text, char *input, const char *exit_msg, int delay_sec); -struct perf_session_env; -int tui__header_window(struct perf_session_env *env); +struct perf_env; +int tui__header_window(struct perf_env *env); void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); unsigned int ui_browser__argv_refresh(struct ui_browser *browser); diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c index f10681717f93..edbeaaf31ace 100644 --- a/tools/perf/ui/browsers/header.c +++ b/tools/perf/ui/browsers/header.c @@ -91,7 +91,7 @@ static int ui__list_menu(int argc, char * const argv[]) return list_menu__run(&menu); } -int tui__header_window(struct perf_session_env *env) +int tui__header_window(struct perf_env *env) { int i, argc = 0; char **argv; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 10c7ec041039..cf86f2d3a5e7 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -26,7 +26,7 @@ struct hist_browser { struct map_symbol *selection; struct hist_browser_timer *hbt; struct pstack *pstack; - struct perf_session_env *env; + struct perf_env *env; int print_seq; bool show_dso; bool show_headers; @@ -1214,7 +1214,7 @@ static int hist_browser__dump(struct hist_browser *browser) static struct hist_browser *hist_browser__new(struct hists *hists, struct hist_browser_timer *hbt, - struct perf_session_env *env) + struct perf_env *env) { struct hist_browser *browser = zalloc(sizeof(*browser)); @@ -1695,7 +1695,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, bool left_exits, struct hist_browser_timer *hbt, float min_pcnt, - struct perf_session_env *env) + struct perf_env *env) { struct hists *hists = evsel__hists(evsel); struct hist_browser *browser = hist_browser__new(hists, hbt, env); @@ -2016,7 +2016,7 @@ struct perf_evsel_menu { struct perf_evsel *selection; bool lost_events, lost_events_warned; float min_pcnt; - struct perf_session_env *env; + struct perf_env *env; }; static void perf_evsel_menu__write(struct ui_browser *browser, @@ -2169,7 +2169,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, int nr_entries, const char *help, struct hist_browser_timer *hbt, float min_pcnt, - struct perf_session_env *env) + struct perf_env *env) { struct perf_evsel *pos; struct perf_evsel_menu menu = { @@ -2202,7 +2202,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt, - struct perf_session_env *env) + struct perf_env *env) { int nr_entries = evlist->nr_entries; diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 9b53b6525ce8..396e4965f0c9 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -66,7 +66,7 @@ struct perf_header; int perf_file_header__read(struct perf_file_header *header, struct perf_header *ph, int fd); -struct perf_session_env { +struct perf_env { char *hostname; char *os_release; char *version; @@ -98,7 +98,7 @@ struct perf_header { u64 data_size; u64 feat_offset; DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); - struct perf_session_env env; + struct perf_env env; }; struct perf_evlist; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index bc528d54e457..de6d58e7f0d5 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -313,7 +313,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt, - struct perf_session_env *env); + struct perf_env *env); int script_browse(const char *script_opt); #else static inline @@ -321,7 +321,7 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, const char *help __maybe_unused, struct hist_browser_timer *hbt __maybe_unused, float min_pcnt __maybe_unused, - struct perf_session_env *env __maybe_unused) + struct perf_env *env __maybe_unused) { return 0; } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 18722e774a69..8a4537ee9bc3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -170,7 +170,7 @@ static void perf_session__delete_threads(struct perf_session *session) machine__delete_threads(&session->machines.host); } -static void perf_session_env__exit(struct perf_session_env *env) +static void perf_session_env__exit(struct perf_env *env) { zfree(&env->hostname); zfree(&env->os_release); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 46ae0532a8a6..1f97ffb158a6 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1853,7 +1853,7 @@ static void vmlinux_path__exit(void) zfree(&vmlinux_path); } -static int vmlinux_path__init(struct perf_session_env *env) +static int vmlinux_path__init(struct perf_env *env) { struct utsname uts; char bf[PATH_MAX]; @@ -1964,7 +1964,7 @@ static bool symbol__read_kptr_restrict(void) return value; } -int symbol__init(struct perf_session_env *env) +int symbol__init(struct perf_env *env) { const char *symfs; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index a4cde92afbad..440ba8ae888f 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -252,8 +252,8 @@ int modules__parse(const char *filename, void *arg, int filename__read_debuglink(const char *filename, char *debuglink, size_t size); -struct perf_session_env; -int symbol__init(struct perf_session_env *env); +struct perf_env; +int symbol__init(struct perf_env *env); void symbol__exit(void); void symbol__elf_init(void); struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); -- cgit v1.2.1 From 2c07144dfce366e21465cc7b0ada9f0b6dc7b7ed Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Fri, 28 Aug 2015 05:48:05 -0400 Subject: perf evlist: Add backpointer for perf_env to evlist Add backpointer to perf_env in evlist, so we can easily access env when processing something where we have a evsel or evlist. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Kan Liang Cc: Adrian Hunter Cc: Andi Kleen Cc: Andy Lutomirski Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1440755289-30939-5-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.h | 1 + tools/perf/util/header.c | 1 + 2 files changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 436e358300b1..b39a6198f4ac 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -56,6 +56,7 @@ struct perf_evlist { struct cpu_map *cpus; struct perf_evsel *selected; struct events_stats stats; + struct perf_env *env; }; struct perf_evsel_str_handler { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 179b2bdd157d..41814547da15 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2514,6 +2514,7 @@ int perf_session__read_header(struct perf_session *session) if (session->evlist == NULL) return -ENOMEM; + session->evlist->env = &header->env; if (perf_data_file__is_pipe(file)) return perf_header__read_pipe(session); -- cgit v1.2.1