From 0ab7368f8dad561b6164b3e942cab00f9565bd37 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 28 Aug 2010 16:46:19 +0100 Subject: perf record: Remove newline character from perror() argument If we include a newline character in the string argument to perror() then the output will be split across two lines like so, Unable to read perf file descriptor : No space left on device Deleting the newline character prints a much more readable error, Unable to read perf file descriptor: No space left on device Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Ingo Molnar Cc: Frederic Weisbecker Cc: Tom Zanussi LKML-Reference: <89e77b54659bc3798b23a5596c2debb7f6f4cf27.1283010281.git.matt@console-pimps.org> Signed-off-by: Matt Fleming Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ff77b805de71..b530beefd9ad 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -353,7 +353,7 @@ try_again: } if (read(fd[nr_cpu][counter][thread_index], &read_data, sizeof(read_data)) == -1) { - perror("Unable to read perf file descriptor\n"); + perror("Unable to read perf file descriptor"); exit(-1); } @@ -626,7 +626,7 @@ static int __cmd_record(int argc, const char **argv) nr_cpus = read_cpu_map(cpu_list); if (nr_cpus < 1) { - perror("failed to collect number of CPUs\n"); + perror("failed to collect number of CPUs"); return -1; } -- cgit v1.2.3 From b44308f54062a4c1dee2602946f481f03739b76d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 26 Oct 2010 15:20:09 -0200 Subject: perf scripting: Shut up 'perf record' final status We want just the script output, not internal details about the record phase. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 4 ++++ tools/perf/builtin-record.c | 4 ++++ tools/perf/builtin-trace.c | 9 +++++---- tools/perf/util/debug.c | 4 ++-- tools/perf/util/debug.h | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 3ee27dccfde9..a91f9f9e6e5c 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -83,6 +83,10 @@ OPTIONS --call-graph:: Do call-graph (stack chain/backtrace) recording. +-q:: +--quiet:: + Don't print any message, useful for scripting. + -v:: --verbose:: Be more verbose (show counter open errors, etc). diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b530beefd9ad..4e75583ddd6d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -761,6 +761,9 @@ static int __cmd_record(int argc, const char **argv) } } + if (quiet) + return 0; + fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); /* @@ -820,6 +823,7 @@ static const struct option options[] = { "do call-graph (stack chain/backtrace) recording"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), + OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), OPT_BOOLEAN('s', "stat", &inherit_stat, "per thread counts"), OPT_BOOLEAN('d', "data", &sample_address, diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index deda1a93131e..2f8df45c4dcb 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -625,12 +625,13 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) dup2(live_pipe[1], 1); close(live_pipe[0]); - __argv = malloc(5 * sizeof(const char *)); + __argv = malloc(6 * sizeof(const char *)); __argv[0] = "/bin/sh"; __argv[1] = record_script_path; - __argv[2] = "-o"; - __argv[3] = "-"; - __argv[4] = NULL; + __argv[2] = "-q"; + __argv[3] = "-o"; + __argv[4] = "-"; + __argv[5] = NULL; execvp("/bin/sh", (char **)__argv); exit(-1); diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index f9c7e3ad1aa7..c8d81b00089d 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -12,8 +12,8 @@ #include "debug.h" #include "util.h" -int verbose = 0; -bool dump_trace = false; +int verbose; +bool dump_trace = false, quiet = false; int eprintf(int level, const char *fmt, ...) { diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 7a17ee061bcb..7b514082bbaf 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -6,7 +6,7 @@ #include "event.h" extern int verbose; -extern bool dump_trace; +extern bool quiet, dump_trace; int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void trace_event(event_t *event); -- cgit v1.2.3 From 22d0594b31046793dfb58b7ce866d7cb0a9862e5 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 26 Oct 2010 15:21:15 -0200 Subject: perf python scripting: Fixup cut'n'paste error in sctop script Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/scripts/python/sctop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py index 547cbe99de68..7a6ec2c7d8ab 100644 --- a/tools/perf/scripts/python/sctop.py +++ b/tools/perf/scripts/python/sctop.py @@ -17,7 +17,7 @@ from perf_trace_context import * from Core import * from Util import * -usage = "perf trace -s syscall-counts.py [comm] [interval]\n"; +usage = "perf trace -s sctop.py [comm] [interval]\n"; for_comm = None default_interval = 3 -- cgit v1.2.3 From 00204c3396469f407bac56e1475ea16e4a279b13 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 26 Oct 2010 17:07:33 -0200 Subject: perf python scripting: Add futex-contention script The equivalent to this SystemTAP script: http://sourceware.org/systemtap/wiki/WSFutexContention [root@doppio ~]# perf trace futex-contention Press control+C to stop and show the summary ^Cnpviewer.bin[15242] lock 7f0a8be19104 contended 29 times, 72806 avg ns npviewer.bin[15242] lock 7f0a8be19130 contended 2 times, 1355 avg ns synergyc[17245] lock f127f4 contended 1 times, 1830569 avg ns firefox[15116] lock 7f2b7238af0c contended 168 times, 1230390 avg ns synergyc[17245] lock f2fc20 contended 1 times, 33149 avg ns npviewer.bin[15255] lock 7f0a8be19074 contended 155 times, 73047 avg ns npviewer.bin[15255] lock 7f0a8be190a0 contended 127 times, 7088 avg ns synergyc[17247] lock f12854 contended 1 times, 46741 avg ns synergyc[17245] lock f12610 contended 1 times, 7358 avg ns [root@doppio ~]# Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- .../python/Perf-Trace-Util/lib/Perf/Trace/Util.py | 18 ++++++++ .../scripts/python/bin/futex-contention-record | 2 + .../scripts/python/bin/futex-contention-report | 4 ++ tools/perf/scripts/python/futex-contention.py | 50 ++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 tools/perf/scripts/python/bin/futex-contention-record create mode 100644 tools/perf/scripts/python/bin/futex-contention-report create mode 100644 tools/perf/scripts/python/futex-contention.py diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py index 99ff1b7a0d2c..13cc02b5893a 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py @@ -8,6 +8,12 @@ import errno, os +FUTEX_WAIT = 0 +FUTEX_WAKE = 1 +FUTEX_PRIVATE_FLAG = 128 +FUTEX_CLOCK_REALTIME = 256 +FUTEX_CMD_MASK = ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) + NSECS_PER_SEC = 1000000000 def avg(total, n): @@ -26,6 +32,18 @@ def nsecs_str(nsecs): str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)), return str +def add_stats(dict, key, value): + if not dict.has_key(key): + dict[key] = (value, value, value, 1) + else: + min, max, avg, count = dict[key] + if value < min: + min = value + if value > max: + max = value + avg = (avg + value) / 2 + dict[key] = (min, max, avg, count + 1) + def clear_term(): print("\x1b[H\x1b[2J") diff --git a/tools/perf/scripts/python/bin/futex-contention-record b/tools/perf/scripts/python/bin/futex-contention-record new file mode 100644 index 000000000000..5ecbb433caf4 --- /dev/null +++ b/tools/perf/scripts/python/bin/futex-contention-record @@ -0,0 +1,2 @@ +#!/bin/bash +perf record -a -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex $@ diff --git a/tools/perf/scripts/python/bin/futex-contention-report b/tools/perf/scripts/python/bin/futex-contention-report new file mode 100644 index 000000000000..c8268138fb7e --- /dev/null +++ b/tools/perf/scripts/python/bin/futex-contention-report @@ -0,0 +1,4 @@ +#!/bin/bash +# description: futext contention measurement + +perf trace $@ -s "$PERF_EXEC_PATH"/scripts/python/futex-contention.py diff --git a/tools/perf/scripts/python/futex-contention.py b/tools/perf/scripts/python/futex-contention.py new file mode 100644 index 000000000000..11e70a388d41 --- /dev/null +++ b/tools/perf/scripts/python/futex-contention.py @@ -0,0 +1,50 @@ +# futex contention +# (c) 2010, Arnaldo Carvalho de Melo +# Licensed under the terms of the GNU GPL License version 2 +# +# Translation of: +# +# http://sourceware.org/systemtap/wiki/WSFutexContention +# +# to perf python scripting. +# +# Measures futex contention + +import os, sys +sys.path.append(os.environ['PERF_EXEC_PATH'] + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') +from Util import * + +process_names = {} +thread_thislock = {} +thread_blocktime = {} + +lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time +process_names = {} # long-lived pid-to-execname mapping + +def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, + nr, uaddr, op, val, utime, uaddr2, val3): + cmd = op & FUTEX_CMD_MASK + if cmd != FUTEX_WAIT: + return # we don't care about originators of WAKE events + + process_names[tid] = comm + thread_thislock[tid] = uaddr + thread_blocktime[tid] = nsecs(s, ns) + +def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, + nr, ret): + if thread_blocktime.has_key(tid): + elapsed = nsecs(s, ns) - thread_blocktime[tid] + add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed) + del thread_blocktime[tid] + del thread_thislock[tid] + +def trace_begin(): + print "Press control+C to stop and show the summary" + +def trace_end(): + for (tid, lock) in lock_waits: + min, max, avg, count = lock_waits[tid, lock] + print "%s[%d] lock %x contended %d times, %d avg ns" % \ + (process_names[tid], tid, lock, count, avg) + -- cgit v1.2.3