diff options
| author | Michal Marek <mmarek@suse.cz> | 2010-08-04 07:59:13 -0400 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2010-08-04 07:59:13 -0400 |
| commit | 772320e84588dcbe1600ffb83e5f328f2209ac2a (patch) | |
| tree | a7de21b79340aeaa17c58126f6b801b82c77b53a /tools/perf/scripts | |
| parent | 1ce53adf13a54375d2a5c7cdbe341b2558389615 (diff) | |
| parent | 9fe6206f400646a2322096b56c59891d530e8d51 (diff) | |
Merge commit 'v2.6.35' into kbuild/kbuild
Conflicts:
arch/powerpc/Makefile
Diffstat (limited to 'tools/perf/scripts')
38 files changed, 976 insertions, 57 deletions
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c index af78d9a52a7d..01a64ad693f2 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c | |||
| @@ -31,13 +31,14 @@ | |||
| 31 | #include "EXTERN.h" | 31 | #include "EXTERN.h" |
| 32 | #include "perl.h" | 32 | #include "perl.h" |
| 33 | #include "XSUB.h" | 33 | #include "XSUB.h" |
| 34 | #include "../../../util/trace-event-perl.h" | 34 | #include "../../../perf.h" |
| 35 | #include "../../../util/trace-event.h" | ||
| 35 | 36 | ||
| 36 | #ifndef PERL_UNUSED_VAR | 37 | #ifndef PERL_UNUSED_VAR |
| 37 | # define PERL_UNUSED_VAR(var) if (0) var = var | 38 | # define PERL_UNUSED_VAR(var) if (0) var = var |
| 38 | #endif | 39 | #endif |
| 39 | 40 | ||
| 40 | #line 41 "Context.c" | 41 | #line 42 "Context.c" |
| 41 | 42 | ||
| 42 | XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */ | 43 | XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */ |
| 43 | XS(XS_Perf__Trace__Context_common_pc) | 44 | XS(XS_Perf__Trace__Context_common_pc) |
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs index fb78006c165e..549cf0467d30 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs | |||
| @@ -22,7 +22,8 @@ | |||
| 22 | #include "EXTERN.h" | 22 | #include "EXTERN.h" |
| 23 | #include "perl.h" | 23 | #include "perl.h" |
| 24 | #include "XSUB.h" | 24 | #include "XSUB.h" |
| 25 | #include "../../../util/trace-event-perl.h" | 25 | #include "../../../perf.h" |
| 26 | #include "../../../util/trace-event.h" | ||
| 26 | 27 | ||
| 27 | MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context | 28 | MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context |
| 28 | PROTOTYPES: ENABLE | 29 | PROTOTYPES: ENABLE |
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm index 052f132ced24..d94b40c8ac85 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm +++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm | |||
| @@ -15,6 +15,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); | |||
| 15 | 15 | ||
| 16 | our @EXPORT = qw( | 16 | our @EXPORT = qw( |
| 17 | avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs | 17 | avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs |
| 18 | clear_term | ||
| 18 | ); | 19 | ); |
| 19 | 20 | ||
| 20 | our $VERSION = '0.01'; | 21 | our $VERSION = '0.01'; |
| @@ -44,7 +45,7 @@ sub nsecs_secs { | |||
| 44 | sub nsecs_nsecs { | 45 | sub nsecs_nsecs { |
| 45 | my ($nsecs) = @_; | 46 | my ($nsecs) = @_; |
| 46 | 47 | ||
| 47 | return $nsecs - nsecs_secs($nsecs); | 48 | return $nsecs % $NSECS_PER_SEC; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | sub nsecs_str { | 51 | sub nsecs_str { |
| @@ -55,6 +56,11 @@ sub nsecs_str { | |||
| 55 | return $str; | 56 | return $str; |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 59 | sub clear_term | ||
| 60 | { | ||
| 61 | print "\x1b[H\x1b[2J"; | ||
| 62 | } | ||
| 63 | |||
| 58 | 1; | 64 | 1; |
| 59 | __END__ | 65 | __END__ |
| 60 | =head1 NAME | 66 | =head1 NAME |
diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-record b/tools/perf/scripts/perl/bin/check-perf-trace-record index c7ec5de2f535..423ad6aed056 100644 --- a/tools/perf/scripts/perl/bin/check-perf-trace-record +++ b/tools/perf/scripts/perl/bin/check-perf-trace-record | |||
| @@ -1,7 +1,2 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | perf record -c 1 -f -a -M -R -e kmem:kmalloc -e irq:softirq_entry | 2 | perf record -a -e kmem:kmalloc -e irq:softirq_entry -e kmem:kfree |
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-report b/tools/perf/scripts/perl/bin/check-perf-trace-report deleted file mode 100644 index 7fc4a033dd49..000000000000 --- a/tools/perf/scripts/perl/bin/check-perf-trace-report +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: useless but exhaustive test script | ||
| 3 | perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl | ||
| 4 | |||
| 5 | |||
| 6 | |||
diff --git a/tools/perf/scripts/perl/bin/failed-syscalls-record b/tools/perf/scripts/perl/bin/failed-syscalls-record new file mode 100644 index 000000000000..eb5846bcb565 --- /dev/null +++ b/tools/perf/scripts/perl/bin/failed-syscalls-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -a -e raw_syscalls:sys_exit $@ | ||
diff --git a/tools/perf/scripts/perl/bin/failed-syscalls-report b/tools/perf/scripts/perl/bin/failed-syscalls-report new file mode 100644 index 000000000000..e3a5e55d54ff --- /dev/null +++ b/tools/perf/scripts/perl/bin/failed-syscalls-report | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide failed syscalls | ||
| 3 | # args: [comm] | ||
| 4 | if [ $# -gt 0 ] ; then | ||
| 5 | if ! expr match "$1" "-" > /dev/null ; then | ||
| 6 | comm=$1 | ||
| 7 | shift | ||
| 8 | fi | ||
| 9 | fi | ||
| 10 | perf trace $@ -s ~/libexec/perf-core/scripts/perl/failed-syscalls.pl $comm | ||
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-record b/tools/perf/scripts/perl/bin/rw-by-file-record index b25056ebf963..5bfaae5a6cba 100644 --- a/tools/perf/scripts/perl/bin/rw-by-file-record +++ b/tools/perf/scripts/perl/bin/rw-by-file-record | |||
| @@ -1,2 +1,3 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_enter_write | 2 | perf record -a -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@ |
| 3 | |||
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-report b/tools/perf/scripts/perl/bin/rw-by-file-report index eddb9ccce6a5..d83070b7eeb5 100644 --- a/tools/perf/scripts/perl/bin/rw-by-file-report +++ b/tools/perf/scripts/perl/bin/rw-by-file-report | |||
| @@ -1,7 +1,13 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: r/w activity for a program, by file | 2 | # description: r/w activity for a program, by file |
| 3 | # args: <comm> | 3 | # args: <comm> |
| 4 | perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1 | 4 | if [ $# -lt 1 ] ; then |
| 5 | echo "usage: rw-by-file <comm>" | ||
| 6 | exit | ||
| 7 | fi | ||
| 8 | comm=$1 | ||
| 9 | shift | ||
| 10 | perf trace $@ -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $comm | ||
| 5 | 11 | ||
| 6 | 12 | ||
| 7 | 13 | ||
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-record b/tools/perf/scripts/perl/bin/rw-by-pid-record index 8903979c5b6c..6e0b2f7755ac 100644 --- a/tools/perf/scripts/perl/bin/rw-by-pid-record +++ b/tools/perf/scripts/perl/bin/rw-by-pid-record | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write | 2 | perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@ |
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-report b/tools/perf/scripts/perl/bin/rw-by-pid-report index 7f44c25cc857..7ef46983f62f 100644 --- a/tools/perf/scripts/perl/bin/rw-by-pid-report +++ b/tools/perf/scripts/perl/bin/rw-by-pid-report | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: system-wide r/w activity | 2 | # description: system-wide r/w activity |
| 3 | perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl | 3 | perf trace $@ -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | 6 | ||
diff --git a/tools/perf/scripts/perl/bin/rwtop-record b/tools/perf/scripts/perl/bin/rwtop-record new file mode 100644 index 000000000000..6e0b2f7755ac --- /dev/null +++ b/tools/perf/scripts/perl/bin/rwtop-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@ | ||
diff --git a/tools/perf/scripts/perl/bin/rwtop-report b/tools/perf/scripts/perl/bin/rwtop-report new file mode 100644 index 000000000000..93e698cd3f38 --- /dev/null +++ b/tools/perf/scripts/perl/bin/rwtop-report | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide r/w top | ||
| 3 | # args: [interval] | ||
| 4 | n_args=0 | ||
| 5 | for i in "$@" | ||
| 6 | do | ||
| 7 | if expr match "$i" "-" > /dev/null ; then | ||
| 8 | break | ||
| 9 | fi | ||
| 10 | n_args=$(( $n_args + 1 )) | ||
| 11 | done | ||
| 12 | if [ "$n_args" -gt 1 ] ; then | ||
| 13 | echo "usage: rwtop-report [interval]" | ||
| 14 | exit | ||
| 15 | fi | ||
| 16 | if [ "$n_args" -gt 0 ] ; then | ||
| 17 | interval=$1 | ||
| 18 | shift | ||
| 19 | fi | ||
| 20 | perf trace $@ -s ~/libexec/perf-core/scripts/perl/rwtop.pl $interval | ||
| 21 | |||
| 22 | |||
| 23 | |||
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-record b/tools/perf/scripts/perl/bin/wakeup-latency-record index 6abedda911a4..9f2acaaae9f0 100644 --- a/tools/perf/scripts/perl/bin/wakeup-latency-record +++ b/tools/perf/scripts/perl/bin/wakeup-latency-record | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | perf record -c 1 -f -a -M -R -e sched:sched_switch -e sched:sched_wakeup | 2 | perf record -a -e sched:sched_switch -e sched:sched_wakeup $@ |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | 5 | ||
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-report b/tools/perf/scripts/perl/bin/wakeup-latency-report index fce3adcb3249..a0d898f9ca1d 100644 --- a/tools/perf/scripts/perl/bin/wakeup-latency-report +++ b/tools/perf/scripts/perl/bin/wakeup-latency-report | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: system-wide min/max/avg wakeup latency | 2 | # description: system-wide min/max/avg wakeup latency |
| 3 | perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl | 3 | perf trace $@ -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | 6 | ||
diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-record b/tools/perf/scripts/perl/bin/workqueue-stats-record index fce6637b19ba..85301f2471ff 100644 --- a/tools/perf/scripts/perl/bin/workqueue-stats-record +++ b/tools/perf/scripts/perl/bin/workqueue-stats-record | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | perf record -c 1 -f -a -M -R -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion | 2 | perf record -a -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@ |
diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-report b/tools/perf/scripts/perl/bin/workqueue-stats-report index 71cfbd182fb9..35081132ef97 100644 --- a/tools/perf/scripts/perl/bin/workqueue-stats-report +++ b/tools/perf/scripts/perl/bin/workqueue-stats-report | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # description: workqueue stats (ins/exe/create/destroy) | 2 | # description: workqueue stats (ins/exe/create/destroy) |
| 3 | perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl | 3 | perf trace $@ -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | 6 | ||
diff --git a/tools/perf/scripts/perl/failed-syscalls.pl b/tools/perf/scripts/perl/failed-syscalls.pl new file mode 100644 index 000000000000..94bc25a347eb --- /dev/null +++ b/tools/perf/scripts/perl/failed-syscalls.pl | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | # failed system call counts | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # Displays system-wide failed system call totals | ||
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | ||
| 7 | |||
| 8 | use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib"; | ||
| 9 | use lib "./Perf-Trace-Util/lib"; | ||
| 10 | use Perf::Trace::Core; | ||
| 11 | use Perf::Trace::Context; | ||
| 12 | use Perf::Trace::Util; | ||
| 13 | |||
| 14 | my $for_comm = shift; | ||
| 15 | |||
| 16 | my %failed_syscalls; | ||
| 17 | |||
| 18 | sub raw_syscalls::sys_exit | ||
| 19 | { | ||
| 20 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
| 21 | $common_pid, $common_comm, | ||
| 22 | $id, $ret) = @_; | ||
| 23 | |||
| 24 | if ($ret < 0) { | ||
| 25 | $failed_syscalls{$common_comm}++; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | sub trace_end | ||
| 30 | { | ||
| 31 | printf("\nfailed syscalls by comm:\n\n"); | ||
| 32 | |||
| 33 | printf("%-20s %10s\n", "comm", "# errors"); | ||
| 34 | printf("%-20s %6s %10s\n", "--------------------", "----------"); | ||
| 35 | |||
| 36 | foreach my $comm (sort {$failed_syscalls{$b} <=> $failed_syscalls{$a}} | ||
| 37 | keys %failed_syscalls) { | ||
| 38 | next if ($for_comm && $comm ne $for_comm); | ||
| 39 | |||
| 40 | printf("%-20s %10s\n", $comm, $failed_syscalls{$comm}); | ||
| 41 | } | ||
| 42 | } | ||
diff --git a/tools/perf/scripts/perl/rw-by-pid.pl b/tools/perf/scripts/perl/rw-by-pid.pl index da601fae1a00..9db23c9daf55 100644 --- a/tools/perf/scripts/perl/rw-by-pid.pl +++ b/tools/perf/scripts/perl/rw-by-pid.pl | |||
| @@ -79,12 +79,12 @@ sub trace_end | |||
| 79 | printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------", | 79 | printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------", |
| 80 | "-----------", "----------", "----------"); | 80 | "-----------", "----------", "----------"); |
| 81 | 81 | ||
| 82 | foreach my $pid (sort {$reads{$b}{bytes_read} <=> | 82 | foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=> |
| 83 | $reads{$a}{bytes_read}} keys %reads) { | 83 | ($reads{$a}{bytes_read} || 0) } keys %reads) { |
| 84 | my $comm = $reads{$pid}{comm}; | 84 | my $comm = $reads{$pid}{comm} || ""; |
| 85 | my $total_reads = $reads{$pid}{total_reads}; | 85 | my $total_reads = $reads{$pid}{total_reads} || 0; |
| 86 | my $bytes_requested = $reads{$pid}{bytes_requested}; | 86 | my $bytes_requested = $reads{$pid}{bytes_requested} || 0; |
| 87 | my $bytes_read = $reads{$pid}{bytes_read}; | 87 | my $bytes_read = $reads{$pid}{bytes_read} || 0; |
| 88 | 88 | ||
| 89 | printf("%6s %-20s %10s %10s %10s\n", $pid, $comm, | 89 | printf("%6s %-20s %10s %10s %10s\n", $pid, $comm, |
| 90 | $total_reads, $bytes_requested, $bytes_read); | 90 | $total_reads, $bytes_requested, $bytes_read); |
| @@ -96,16 +96,23 @@ sub trace_end | |||
| 96 | printf("%6s %20s %6s %10s\n", "------", "--------------------", | 96 | printf("%6s %20s %6s %10s\n", "------", "--------------------", |
| 97 | "------", "----------"); | 97 | "------", "----------"); |
| 98 | 98 | ||
| 99 | foreach my $pid (keys %reads) { | 99 | my @errcounts = (); |
| 100 | my $comm = $reads{$pid}{comm}; | ||
| 101 | foreach my $err (sort {$reads{$b}{comm} cmp $reads{$a}{comm}} | ||
| 102 | keys %{$reads{$pid}{errors}}) { | ||
| 103 | my $errors = $reads{$pid}{errors}{$err}; | ||
| 104 | 100 | ||
| 105 | printf("%6d %-20s %6d %10s\n", $pid, $comm, $err, $errors); | 101 | foreach my $pid (keys %reads) { |
| 102 | foreach my $error (keys %{$reads{$pid}{errors}}) { | ||
| 103 | my $comm = $reads{$pid}{comm} || ""; | ||
| 104 | my $errcount = $reads{$pid}{errors}{$error} || 0; | ||
| 105 | push @errcounts, [$pid, $comm, $error, $errcount]; | ||
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts; | ||
| 110 | |||
| 111 | for my $i (0 .. $#errcounts) { | ||
| 112 | printf("%6d %-20s %6d %10s\n", $errcounts[$i][0], | ||
| 113 | $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]); | ||
| 114 | } | ||
| 115 | |||
| 109 | printf("\nwrite counts by pid:\n\n"); | 116 | printf("\nwrite counts by pid:\n\n"); |
| 110 | 117 | ||
| 111 | printf("%6s %20s %10s %10s\n", "pid", "comm", | 118 | printf("%6s %20s %10s %10s\n", "pid", "comm", |
| @@ -113,11 +120,11 @@ sub trace_end | |||
| 113 | printf("%6s %-20s %10s %10s\n", "------", "--------------------", | 120 | printf("%6s %-20s %10s %10s\n", "------", "--------------------", |
| 114 | "-----------", "----------"); | 121 | "-----------", "----------"); |
| 115 | 122 | ||
| 116 | foreach my $pid (sort {$writes{$b}{bytes_written} <=> | 123 | foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=> |
| 117 | $writes{$a}{bytes_written}} keys %writes) { | 124 | ($writes{$a}{bytes_written} || 0)} keys %writes) { |
| 118 | my $comm = $writes{$pid}{comm}; | 125 | my $comm = $writes{$pid}{comm} || ""; |
| 119 | my $total_writes = $writes{$pid}{total_writes}; | 126 | my $total_writes = $writes{$pid}{total_writes} || 0; |
| 120 | my $bytes_written = $writes{$pid}{bytes_written}; | 127 | my $bytes_written = $writes{$pid}{bytes_written} || 0; |
| 121 | 128 | ||
| 122 | printf("%6s %-20s %10s %10s\n", $pid, $comm, | 129 | printf("%6s %-20s %10s %10s\n", $pid, $comm, |
| 123 | $total_writes, $bytes_written); | 130 | $total_writes, $bytes_written); |
| @@ -129,16 +136,23 @@ sub trace_end | |||
| 129 | printf("%6s %20s %6s %10s\n", "------", "--------------------", | 136 | printf("%6s %20s %6s %10s\n", "------", "--------------------", |
| 130 | "------", "----------"); | 137 | "------", "----------"); |
| 131 | 138 | ||
| 132 | foreach my $pid (keys %writes) { | 139 | @errcounts = (); |
| 133 | my $comm = $writes{$pid}{comm}; | ||
| 134 | foreach my $err (sort {$writes{$b}{comm} cmp $writes{$a}{comm}} | ||
| 135 | keys %{$writes{$pid}{errors}}) { | ||
| 136 | my $errors = $writes{$pid}{errors}{$err}; | ||
| 137 | 140 | ||
| 138 | printf("%6d %-20s %6d %10s\n", $pid, $comm, $err, $errors); | 141 | foreach my $pid (keys %writes) { |
| 142 | foreach my $error (keys %{$writes{$pid}{errors}}) { | ||
| 143 | my $comm = $writes{$pid}{comm} || ""; | ||
| 144 | my $errcount = $writes{$pid}{errors}{$error} || 0; | ||
| 145 | push @errcounts, [$pid, $comm, $error, $errcount]; | ||
| 139 | } | 146 | } |
| 140 | } | 147 | } |
| 141 | 148 | ||
| 149 | @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts; | ||
| 150 | |||
| 151 | for my $i (0 .. $#errcounts) { | ||
| 152 | printf("%6d %-20s %6d %10s\n", $errcounts[$i][0], | ||
| 153 | $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]); | ||
| 154 | } | ||
| 155 | |||
| 142 | print_unhandled(); | 156 | print_unhandled(); |
| 143 | } | 157 | } |
| 144 | 158 | ||
diff --git a/tools/perf/scripts/perl/rwtop.pl b/tools/perf/scripts/perl/rwtop.pl new file mode 100644 index 000000000000..4bb3ecd33472 --- /dev/null +++ b/tools/perf/scripts/perl/rwtop.pl | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | #!/usr/bin/perl -w | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | |||
| 5 | # read/write top | ||
| 6 | # | ||
| 7 | # Periodically displays system-wide r/w call activity, broken down by | ||
| 8 | # pid. If an [interval] arg is specified, the display will be | ||
| 9 | # refreshed every [interval] seconds. The default interval is 3 | ||
| 10 | # seconds. | ||
| 11 | |||
| 12 | use 5.010000; | ||
| 13 | use strict; | ||
| 14 | use warnings; | ||
| 15 | |||
| 16 | use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib"; | ||
| 17 | use lib "./Perf-Trace-Util/lib"; | ||
| 18 | use Perf::Trace::Core; | ||
| 19 | use Perf::Trace::Util; | ||
| 20 | |||
| 21 | my $default_interval = 3; | ||
| 22 | my $nlines = 20; | ||
| 23 | my $print_thread; | ||
| 24 | my $print_pending = 0; | ||
| 25 | |||
| 26 | my %reads; | ||
| 27 | my %writes; | ||
| 28 | |||
| 29 | my $interval = shift; | ||
| 30 | if (!$interval) { | ||
| 31 | $interval = $default_interval; | ||
| 32 | } | ||
| 33 | |||
| 34 | sub syscalls::sys_exit_read | ||
| 35 | { | ||
| 36 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
| 37 | $common_pid, $common_comm, | ||
| 38 | $nr, $ret) = @_; | ||
| 39 | |||
| 40 | print_check(); | ||
| 41 | |||
| 42 | if ($ret > 0) { | ||
| 43 | $reads{$common_pid}{bytes_read} += $ret; | ||
| 44 | } else { | ||
| 45 | if (!defined ($reads{$common_pid}{bytes_read})) { | ||
| 46 | $reads{$common_pid}{bytes_read} = 0; | ||
| 47 | } | ||
| 48 | $reads{$common_pid}{errors}{$ret}++; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | sub syscalls::sys_enter_read | ||
| 53 | { | ||
| 54 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
| 55 | $common_pid, $common_comm, | ||
| 56 | $nr, $fd, $buf, $count) = @_; | ||
| 57 | |||
| 58 | print_check(); | ||
| 59 | |||
| 60 | $reads{$common_pid}{bytes_requested} += $count; | ||
| 61 | $reads{$common_pid}{total_reads}++; | ||
| 62 | $reads{$common_pid}{comm} = $common_comm; | ||
| 63 | } | ||
| 64 | |||
| 65 | sub syscalls::sys_exit_write | ||
| 66 | { | ||
| 67 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
| 68 | $common_pid, $common_comm, | ||
| 69 | $nr, $ret) = @_; | ||
| 70 | |||
| 71 | print_check(); | ||
| 72 | |||
| 73 | if ($ret <= 0) { | ||
| 74 | $writes{$common_pid}{errors}{$ret}++; | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | sub syscalls::sys_enter_write | ||
| 79 | { | ||
| 80 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
| 81 | $common_pid, $common_comm, | ||
| 82 | $nr, $fd, $buf, $count) = @_; | ||
| 83 | |||
| 84 | print_check(); | ||
| 85 | |||
| 86 | $writes{$common_pid}{bytes_written} += $count; | ||
| 87 | $writes{$common_pid}{total_writes}++; | ||
| 88 | $writes{$common_pid}{comm} = $common_comm; | ||
| 89 | } | ||
| 90 | |||
| 91 | sub trace_begin | ||
| 92 | { | ||
| 93 | $SIG{ALRM} = \&set_print_pending; | ||
| 94 | alarm 1; | ||
| 95 | } | ||
| 96 | |||
| 97 | sub trace_end | ||
| 98 | { | ||
| 99 | print_unhandled(); | ||
| 100 | print_totals(); | ||
| 101 | } | ||
| 102 | |||
| 103 | sub print_check() | ||
| 104 | { | ||
| 105 | if ($print_pending == 1) { | ||
| 106 | $print_pending = 0; | ||
| 107 | print_totals(); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | sub set_print_pending() | ||
| 112 | { | ||
| 113 | $print_pending = 1; | ||
| 114 | alarm $interval; | ||
| 115 | } | ||
| 116 | |||
| 117 | sub print_totals | ||
| 118 | { | ||
| 119 | my $count; | ||
| 120 | |||
| 121 | $count = 0; | ||
| 122 | |||
| 123 | clear_term(); | ||
| 124 | |||
| 125 | printf("\nread counts by pid:\n\n"); | ||
| 126 | |||
| 127 | printf("%6s %20s %10s %10s %10s\n", "pid", "comm", | ||
| 128 | "# reads", "bytes_req", "bytes_read"); | ||
| 129 | printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------", | ||
| 130 | "----------", "----------", "----------"); | ||
| 131 | |||
| 132 | foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=> | ||
| 133 | ($reads{$a}{bytes_read} || 0) } keys %reads) { | ||
| 134 | my $comm = $reads{$pid}{comm} || ""; | ||
| 135 | my $total_reads = $reads{$pid}{total_reads} || 0; | ||
| 136 | my $bytes_requested = $reads{$pid}{bytes_requested} || 0; | ||
| 137 | my $bytes_read = $reads{$pid}{bytes_read} || 0; | ||
| 138 | |||
| 139 | printf("%6s %-20s %10s %10s %10s\n", $pid, $comm, | ||
| 140 | $total_reads, $bytes_requested, $bytes_read); | ||
| 141 | |||
| 142 | if (++$count == $nlines) { | ||
| 143 | last; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | $count = 0; | ||
| 148 | |||
| 149 | printf("\nwrite counts by pid:\n\n"); | ||
| 150 | |||
| 151 | printf("%6s %20s %10s %13s\n", "pid", "comm", | ||
| 152 | "# writes", "bytes_written"); | ||
| 153 | printf("%6s %-20s %10s %13s\n", "------", "--------------------", | ||
| 154 | "----------", "-------------"); | ||
| 155 | |||
| 156 | foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=> | ||
| 157 | ($writes{$a}{bytes_written} || 0)} keys %writes) { | ||
| 158 | my $comm = $writes{$pid}{comm} || ""; | ||
| 159 | my $total_writes = $writes{$pid}{total_writes} || 0; | ||
| 160 | my $bytes_written = $writes{$pid}{bytes_written} || 0; | ||
| 161 | |||
| 162 | printf("%6s %-20s %10s %13s\n", $pid, $comm, | ||
| 163 | $total_writes, $bytes_written); | ||
| 164 | |||
| 165 | if (++$count == $nlines) { | ||
| 166 | last; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | %reads = (); | ||
| 171 | %writes = (); | ||
| 172 | } | ||
| 173 | |||
| 174 | my %unhandled; | ||
| 175 | |||
| 176 | sub print_unhandled | ||
| 177 | { | ||
| 178 | if ((scalar keys %unhandled) == 0) { | ||
| 179 | return; | ||
| 180 | } | ||
| 181 | |||
| 182 | print "\nunhandled events:\n\n"; | ||
| 183 | |||
| 184 | printf("%-40s %10s\n", "event", "count"); | ||
| 185 | printf("%-40s %10s\n", "----------------------------------------", | ||
| 186 | "-----------"); | ||
| 187 | |||
| 188 | foreach my $event_name (keys %unhandled) { | ||
| 189 | printf("%-40s %10d\n", $event_name, $unhandled{$event_name}); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | sub trace_unhandled | ||
| 194 | { | ||
| 195 | my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs, | ||
| 196 | $common_pid, $common_comm) = @_; | ||
| 197 | |||
| 198 | $unhandled{$event_name}++; | ||
| 199 | } | ||
diff --git a/tools/perf/scripts/perl/wakeup-latency.pl b/tools/perf/scripts/perl/wakeup-latency.pl index ed58ef284e23..d9143dcec6c6 100644 --- a/tools/perf/scripts/perl/wakeup-latency.pl +++ b/tools/perf/scripts/perl/wakeup-latency.pl | |||
| @@ -22,8 +22,8 @@ my %last_wakeup; | |||
| 22 | 22 | ||
| 23 | my $max_wakeup_latency; | 23 | my $max_wakeup_latency; |
| 24 | my $min_wakeup_latency; | 24 | my $min_wakeup_latency; |
| 25 | my $total_wakeup_latency; | 25 | my $total_wakeup_latency = 0; |
| 26 | my $total_wakeups; | 26 | my $total_wakeups = 0; |
| 27 | 27 | ||
| 28 | sub sched::sched_switch | 28 | sub sched::sched_switch |
| 29 | { | 29 | { |
| @@ -67,8 +67,12 @@ sub trace_end | |||
| 67 | { | 67 | { |
| 68 | printf("wakeup_latency stats:\n\n"); | 68 | printf("wakeup_latency stats:\n\n"); |
| 69 | print "total_wakeups: $total_wakeups\n"; | 69 | print "total_wakeups: $total_wakeups\n"; |
| 70 | printf("avg_wakeup_latency (ns): %u\n", | 70 | if ($total_wakeups) { |
| 71 | avg($total_wakeup_latency, $total_wakeups)); | 71 | printf("avg_wakeup_latency (ns): %u\n", |
| 72 | avg($total_wakeup_latency, $total_wakeups)); | ||
| 73 | } else { | ||
| 74 | printf("avg_wakeup_latency (ns): N/A\n"); | ||
| 75 | } | ||
| 72 | printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency); | 76 | printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency); |
| 73 | printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency); | 77 | printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency); |
| 74 | 78 | ||
diff --git a/tools/perf/scripts/perl/workqueue-stats.pl b/tools/perf/scripts/perl/workqueue-stats.pl index 511302c8a494..b84b12699b70 100644 --- a/tools/perf/scripts/perl/workqueue-stats.pl +++ b/tools/perf/scripts/perl/workqueue-stats.pl | |||
| @@ -71,9 +71,9 @@ sub trace_end | |||
| 71 | printf("%3s %6s %6s\t%-20s\n", "---", "---", "----", "----"); | 71 | printf("%3s %6s %6s\t%-20s\n", "---", "---", "----", "----"); |
| 72 | foreach my $pidhash (@cpus) { | 72 | foreach my $pidhash (@cpus) { |
| 73 | while ((my $pid, my $wqhash) = each %$pidhash) { | 73 | while ((my $pid, my $wqhash) = each %$pidhash) { |
| 74 | my $ins = $$wqhash{'inserted'}; | 74 | my $ins = $$wqhash{'inserted'} || 0; |
| 75 | my $exe = $$wqhash{'executed'}; | 75 | my $exe = $$wqhash{'executed'} || 0; |
| 76 | my $comm = $$wqhash{'comm'}; | 76 | my $comm = $$wqhash{'comm'} || ""; |
| 77 | if ($ins || $exe) { | 77 | if ($ins || $exe) { |
| 78 | printf("%3u %6u %6u\t%-20s\n", $cpu, $ins, $exe, $comm); | 78 | printf("%3u %6u %6u\t%-20s\n", $cpu, $ins, $exe, $comm); |
| 79 | } | 79 | } |
| @@ -87,9 +87,9 @@ sub trace_end | |||
| 87 | printf("%3s %6s %6s\t%-20s\n", "---", "-------", "---------", "----"); | 87 | printf("%3s %6s %6s\t%-20s\n", "---", "-------", "---------", "----"); |
| 88 | foreach my $pidhash (@cpus) { | 88 | foreach my $pidhash (@cpus) { |
| 89 | while ((my $pid, my $wqhash) = each %$pidhash) { | 89 | while ((my $pid, my $wqhash) = each %$pidhash) { |
| 90 | my $created = $$wqhash{'created'}; | 90 | my $created = $$wqhash{'created'} || 0; |
| 91 | my $destroyed = $$wqhash{'destroyed'}; | 91 | my $destroyed = $$wqhash{'destroyed'} || 0; |
| 92 | my $comm = $$wqhash{'comm'}; | 92 | my $comm = $$wqhash{'comm'} || ""; |
| 93 | if ($created || $destroyed) { | 93 | if ($created || $destroyed) { |
| 94 | printf("%3u %6u %6u\t%-20s\n", $cpu, $created, $destroyed, | 94 | printf("%3u %6u %6u\t%-20s\n", $cpu, $created, $destroyed, |
| 95 | $comm); | 95 | $comm); |
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c new file mode 100644 index 000000000000..957085dd5d8d --- /dev/null +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | /* | ||
| 2 | * Context.c. Python interfaces for perf trace. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Tom Zanussi <tzanussi@gmail.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <Python.h> | ||
| 23 | #include "../../../perf.h" | ||
| 24 | #include "../../../util/trace-event.h" | ||
| 25 | |||
| 26 | PyMODINIT_FUNC initperf_trace_context(void); | ||
| 27 | |||
| 28 | static PyObject *perf_trace_context_common_pc(PyObject *self, PyObject *args) | ||
| 29 | { | ||
| 30 | static struct scripting_context *scripting_context; | ||
| 31 | PyObject *context; | ||
| 32 | int retval; | ||
| 33 | |||
| 34 | if (!PyArg_ParseTuple(args, "O", &context)) | ||
| 35 | return NULL; | ||
| 36 | |||
| 37 | scripting_context = PyCObject_AsVoidPtr(context); | ||
| 38 | retval = common_pc(scripting_context); | ||
| 39 | |||
| 40 | return Py_BuildValue("i", retval); | ||
| 41 | } | ||
| 42 | |||
| 43 | static PyObject *perf_trace_context_common_flags(PyObject *self, | ||
| 44 | PyObject *args) | ||
| 45 | { | ||
| 46 | static struct scripting_context *scripting_context; | ||
| 47 | PyObject *context; | ||
| 48 | int retval; | ||
| 49 | |||
| 50 | if (!PyArg_ParseTuple(args, "O", &context)) | ||
| 51 | return NULL; | ||
| 52 | |||
| 53 | scripting_context = PyCObject_AsVoidPtr(context); | ||
| 54 | retval = common_flags(scripting_context); | ||
| 55 | |||
| 56 | return Py_BuildValue("i", retval); | ||
| 57 | } | ||
| 58 | |||
| 59 | static PyObject *perf_trace_context_common_lock_depth(PyObject *self, | ||
| 60 | PyObject *args) | ||
| 61 | { | ||
| 62 | static struct scripting_context *scripting_context; | ||
| 63 | PyObject *context; | ||
| 64 | int retval; | ||
| 65 | |||
| 66 | if (!PyArg_ParseTuple(args, "O", &context)) | ||
| 67 | return NULL; | ||
| 68 | |||
| 69 | scripting_context = PyCObject_AsVoidPtr(context); | ||
| 70 | retval = common_lock_depth(scripting_context); | ||
| 71 | |||
| 72 | return Py_BuildValue("i", retval); | ||
| 73 | } | ||
| 74 | |||
| 75 | static PyMethodDef ContextMethods[] = { | ||
| 76 | { "common_pc", perf_trace_context_common_pc, METH_VARARGS, | ||
| 77 | "Get the common preempt count event field value."}, | ||
| 78 | { "common_flags", perf_trace_context_common_flags, METH_VARARGS, | ||
| 79 | "Get the common flags event field value."}, | ||
| 80 | { "common_lock_depth", perf_trace_context_common_lock_depth, | ||
| 81 | METH_VARARGS, "Get the common lock depth event field value."}, | ||
| 82 | { NULL, NULL, 0, NULL} | ||
| 83 | }; | ||
| 84 | |||
| 85 | PyMODINIT_FUNC initperf_trace_context(void) | ||
| 86 | { | ||
| 87 | (void) Py_InitModule("perf_trace_context", ContextMethods); | ||
| 88 | } | ||
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py new file mode 100644 index 000000000000..1dc464ee2ca8 --- /dev/null +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | # Core.py - Python extension for perf trace, core functions | ||
| 2 | # | ||
| 3 | # Copyright (C) 2010 by Tom Zanussi <tzanussi@gmail.com> | ||
| 4 | # | ||
| 5 | # This software may be distributed under the terms of the GNU General | ||
| 6 | # Public License ("GPL") version 2 as published by the Free Software | ||
| 7 | # Foundation. | ||
| 8 | |||
| 9 | from collections import defaultdict | ||
| 10 | |||
| 11 | def autodict(): | ||
| 12 | return defaultdict(autodict) | ||
| 13 | |||
| 14 | flag_fields = autodict() | ||
| 15 | symbolic_fields = autodict() | ||
| 16 | |||
| 17 | def define_flag_field(event_name, field_name, delim): | ||
| 18 | flag_fields[event_name][field_name]['delim'] = delim | ||
| 19 | |||
| 20 | def define_flag_value(event_name, field_name, value, field_str): | ||
| 21 | flag_fields[event_name][field_name]['values'][value] = field_str | ||
| 22 | |||
| 23 | def define_symbolic_field(event_name, field_name): | ||
| 24 | # nothing to do, really | ||
| 25 | pass | ||
| 26 | |||
| 27 | def define_symbolic_value(event_name, field_name, value, field_str): | ||
| 28 | symbolic_fields[event_name][field_name]['values'][value] = field_str | ||
| 29 | |||
| 30 | def flag_str(event_name, field_name, value): | ||
| 31 | string = "" | ||
| 32 | |||
| 33 | if flag_fields[event_name][field_name]: | ||
| 34 | print_delim = 0 | ||
| 35 | keys = flag_fields[event_name][field_name]['values'].keys() | ||
| 36 | keys.sort() | ||
| 37 | for idx in keys: | ||
| 38 | if not value and not idx: | ||
| 39 | string += flag_fields[event_name][field_name]['values'][idx] | ||
| 40 | break | ||
| 41 | if idx and (value & idx) == idx: | ||
| 42 | if print_delim and flag_fields[event_name][field_name]['delim']: | ||
| 43 | string += " " + flag_fields[event_name][field_name]['delim'] + " " | ||
| 44 | string += flag_fields[event_name][field_name]['values'][idx] | ||
| 45 | print_delim = 1 | ||
| 46 | value &= ~idx | ||
| 47 | |||
| 48 | return string | ||
| 49 | |||
| 50 | def symbol_str(event_name, field_name, value): | ||
| 51 | string = "" | ||
| 52 | |||
| 53 | if symbolic_fields[event_name][field_name]: | ||
| 54 | keys = symbolic_fields[event_name][field_name]['values'].keys() | ||
| 55 | keys.sort() | ||
| 56 | for idx in keys: | ||
| 57 | if not value and not idx: | ||
| 58 | string = symbolic_fields[event_name][field_name]['values'][idx] | ||
| 59 | break | ||
| 60 | if (value == idx): | ||
| 61 | string = symbolic_fields[event_name][field_name]['values'][idx] | ||
| 62 | break | ||
| 63 | |||
| 64 | return string | ||
| 65 | |||
| 66 | trace_flags = { 0x00: "NONE", \ | ||
| 67 | 0x01: "IRQS_OFF", \ | ||
| 68 | 0x02: "IRQS_NOSUPPORT", \ | ||
| 69 | 0x04: "NEED_RESCHED", \ | ||
| 70 | 0x08: "HARDIRQ", \ | ||
| 71 | 0x10: "SOFTIRQ" } | ||
| 72 | |||
| 73 | def trace_flag_str(value): | ||
| 74 | string = "" | ||
| 75 | print_delim = 0 | ||
| 76 | |||
| 77 | keys = trace_flags.keys() | ||
| 78 | |||
| 79 | for idx in keys: | ||
| 80 | if not value and not idx: | ||
| 81 | string += "NONE" | ||
| 82 | break | ||
| 83 | |||
| 84 | if idx and (value & idx) == idx: | ||
| 85 | if print_delim: | ||
| 86 | string += " | "; | ||
| 87 | string += trace_flags[idx] | ||
| 88 | print_delim = 1 | ||
| 89 | value &= ~idx | ||
| 90 | |||
| 91 | return string | ||
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 new file mode 100644 index 000000000000..9689bc0acd9f --- /dev/null +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | # Util.py - Python extension for perf trace, miscellaneous utility code | ||
| 2 | # | ||
| 3 | # Copyright (C) 2010 by Tom Zanussi <tzanussi@gmail.com> | ||
| 4 | # | ||
| 5 | # This software may be distributed under the terms of the GNU General | ||
| 6 | # Public License ("GPL") version 2 as published by the Free Software | ||
| 7 | # Foundation. | ||
| 8 | |||
| 9 | NSECS_PER_SEC = 1000000000 | ||
| 10 | |||
| 11 | def avg(total, n): | ||
| 12 | return total / n | ||
| 13 | |||
| 14 | def nsecs(secs, nsecs): | ||
| 15 | return secs * NSECS_PER_SEC + nsecs | ||
| 16 | |||
| 17 | def nsecs_secs(nsecs): | ||
| 18 | return nsecs / NSECS_PER_SEC | ||
| 19 | |||
| 20 | def nsecs_nsecs(nsecs): | ||
| 21 | return nsecs % NSECS_PER_SEC | ||
| 22 | |||
| 23 | def nsecs_str(nsecs): | ||
| 24 | str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)), | ||
| 25 | return str | ||
| 26 | |||
| 27 | def clear_term(): | ||
| 28 | print("\x1b[H\x1b[2J") | ||
diff --git a/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record new file mode 100644 index 000000000000..eb5846bcb565 --- /dev/null +++ b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -a -e raw_syscalls:sys_exit $@ | ||
diff --git a/tools/perf/scripts/python/bin/failed-syscalls-by-pid-report b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-report new file mode 100644 index 000000000000..30293545fcc2 --- /dev/null +++ b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-report | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide failed syscalls, by pid | ||
| 3 | # args: [comm] | ||
| 4 | if [ $# -gt 0 ] ; then | ||
| 5 | if ! expr match "$1" "-" > /dev/null ; then | ||
| 6 | comm=$1 | ||
| 7 | shift | ||
| 8 | fi | ||
| 9 | fi | ||
| 10 | perf trace $@ -s ~/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py $comm | ||
diff --git a/tools/perf/scripts/python/bin/sctop-record b/tools/perf/scripts/python/bin/sctop-record new file mode 100644 index 000000000000..1fc5998b721d --- /dev/null +++ b/tools/perf/scripts/python/bin/sctop-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -a -e raw_syscalls:sys_enter $@ | ||
diff --git a/tools/perf/scripts/python/bin/sctop-report b/tools/perf/scripts/python/bin/sctop-report new file mode 100644 index 000000000000..b01c842ae7b4 --- /dev/null +++ b/tools/perf/scripts/python/bin/sctop-report | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: syscall top | ||
| 3 | # args: [comm] [interval] | ||
| 4 | n_args=0 | ||
| 5 | for i in "$@" | ||
| 6 | do | ||
| 7 | if expr match "$i" "-" > /dev/null ; then | ||
| 8 | break | ||
| 9 | fi | ||
| 10 | n_args=$(( $n_args + 1 )) | ||
| 11 | done | ||
| 12 | if [ "$n_args" -gt 2 ] ; then | ||
| 13 | echo "usage: sctop-report [comm] [interval]" | ||
| 14 | exit | ||
| 15 | fi | ||
| 16 | if [ "$n_args" -gt 1 ] ; then | ||
| 17 | comm=$1 | ||
| 18 | interval=$2 | ||
| 19 | shift 2 | ||
| 20 | elif [ "$n_args" -gt 0 ] ; then | ||
| 21 | interval=$1 | ||
| 22 | shift | ||
| 23 | fi | ||
| 24 | perf trace $@ -s ~/libexec/perf-core/scripts/python/sctop.py $comm $interval | ||
diff --git a/tools/perf/scripts/python/bin/syscall-counts-by-pid-record b/tools/perf/scripts/python/bin/syscall-counts-by-pid-record new file mode 100644 index 000000000000..1fc5998b721d --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-by-pid-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -a -e raw_syscalls:sys_enter $@ | ||
diff --git a/tools/perf/scripts/python/bin/syscall-counts-by-pid-report b/tools/perf/scripts/python/bin/syscall-counts-by-pid-report new file mode 100644 index 000000000000..9e9d8ddd72ce --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-by-pid-report | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide syscall counts, by pid | ||
| 3 | # args: [comm] | ||
| 4 | if [ $# -gt 0 ] ; then | ||
| 5 | if ! expr match "$1" "-" > /dev/null ; then | ||
| 6 | comm=$1 | ||
| 7 | shift | ||
| 8 | fi | ||
| 9 | fi | ||
| 10 | perf trace $@ -s ~/libexec/perf-core/scripts/python/syscall-counts-by-pid.py $comm | ||
diff --git a/tools/perf/scripts/python/bin/syscall-counts-record b/tools/perf/scripts/python/bin/syscall-counts-record new file mode 100644 index 000000000000..1fc5998b721d --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -a -e raw_syscalls:sys_enter $@ | ||
diff --git a/tools/perf/scripts/python/bin/syscall-counts-report b/tools/perf/scripts/python/bin/syscall-counts-report new file mode 100644 index 000000000000..dc076b618796 --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-report | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide syscall counts | ||
| 3 | # args: [comm] | ||
| 4 | if [ $# -gt 0 ] ; then | ||
| 5 | if ! expr match "$1" "-" > /dev/null ; then | ||
| 6 | comm=$1 | ||
| 7 | shift | ||
| 8 | fi | ||
| 9 | fi | ||
| 10 | perf trace $@ -s ~/libexec/perf-core/scripts/python/syscall-counts.py $comm | ||
diff --git a/tools/perf/scripts/python/check-perf-trace.py b/tools/perf/scripts/python/check-perf-trace.py new file mode 100644 index 000000000000..d9f7893e315c --- /dev/null +++ b/tools/perf/scripts/python/check-perf-trace.py | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | # perf trace event handlers, generated by perf trace -g python | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # This script tests basic functionality such as flag and symbol | ||
| 6 | # strings, common_xxx() calls back into perf, begin, end, unhandled | ||
| 7 | # events, etc. Basically, if this script runs successfully and | ||
| 8 | # displays expected results, Python scripting support should be ok. | ||
| 9 | |||
| 10 | import os | ||
| 11 | import sys | ||
| 12 | |||
| 13 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
| 14 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
| 15 | |||
| 16 | from Core import * | ||
| 17 | from perf_trace_context import * | ||
| 18 | |||
| 19 | unhandled = autodict() | ||
| 20 | |||
| 21 | def trace_begin(): | ||
| 22 | print "trace_begin" | ||
| 23 | pass | ||
| 24 | |||
| 25 | def trace_end(): | ||
| 26 | print_unhandled() | ||
| 27 | |||
| 28 | def irq__softirq_entry(event_name, context, common_cpu, | ||
| 29 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 30 | vec): | ||
| 31 | print_header(event_name, common_cpu, common_secs, common_nsecs, | ||
| 32 | common_pid, common_comm) | ||
| 33 | |||
| 34 | print_uncommon(context) | ||
| 35 | |||
| 36 | print "vec=%s\n" % \ | ||
| 37 | (symbol_str("irq__softirq_entry", "vec", vec)), | ||
| 38 | |||
| 39 | def kmem__kmalloc(event_name, context, common_cpu, | ||
| 40 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 41 | call_site, ptr, bytes_req, bytes_alloc, | ||
| 42 | gfp_flags): | ||
| 43 | print_header(event_name, common_cpu, common_secs, common_nsecs, | ||
| 44 | common_pid, common_comm) | ||
| 45 | |||
| 46 | print_uncommon(context) | ||
| 47 | |||
| 48 | print "call_site=%u, ptr=%u, bytes_req=%u, " \ | ||
| 49 | "bytes_alloc=%u, gfp_flags=%s\n" % \ | ||
| 50 | (call_site, ptr, bytes_req, bytes_alloc, | ||
| 51 | |||
| 52 | flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)), | ||
| 53 | |||
| 54 | def trace_unhandled(event_name, context, event_fields_dict): | ||
| 55 | try: | ||
| 56 | unhandled[event_name] += 1 | ||
| 57 | except TypeError: | ||
| 58 | unhandled[event_name] = 1 | ||
| 59 | |||
| 60 | def print_header(event_name, cpu, secs, nsecs, pid, comm): | ||
| 61 | print "%-20s %5u %05u.%09u %8u %-20s " % \ | ||
| 62 | (event_name, cpu, secs, nsecs, pid, comm), | ||
| 63 | |||
| 64 | # print trace fields not included in handler args | ||
| 65 | def print_uncommon(context): | ||
| 66 | print "common_preempt_count=%d, common_flags=%s, common_lock_depth=%d, " \ | ||
| 67 | % (common_pc(context), trace_flag_str(common_flags(context)), \ | ||
| 68 | common_lock_depth(context)) | ||
| 69 | |||
| 70 | def print_unhandled(): | ||
| 71 | keys = unhandled.keys() | ||
| 72 | if not keys: | ||
| 73 | return | ||
| 74 | |||
| 75 | print "\nunhandled events:\n\n", | ||
| 76 | |||
| 77 | print "%-40s %10s\n" % ("event", "count"), | ||
| 78 | print "%-40s %10s\n" % ("----------------------------------------", \ | ||
| 79 | "-----------"), | ||
| 80 | |||
| 81 | for event_name in keys: | ||
| 82 | print "%-40s %10d\n" % (event_name, unhandled[event_name]) | ||
diff --git a/tools/perf/scripts/python/failed-syscalls-by-pid.py b/tools/perf/scripts/python/failed-syscalls-by-pid.py new file mode 100644 index 000000000000..0ca02278fe69 --- /dev/null +++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | # failed system call counts, by pid | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # Displays system-wide failed system call totals, broken down by pid. | ||
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | ||
| 7 | |||
| 8 | import os | ||
| 9 | import sys | ||
| 10 | |||
| 11 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
| 12 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
| 13 | |||
| 14 | from perf_trace_context import * | ||
| 15 | from Core import * | ||
| 16 | |||
| 17 | usage = "perf trace -s syscall-counts-by-pid.py [comm]\n"; | ||
| 18 | |||
| 19 | for_comm = None | ||
| 20 | |||
| 21 | if len(sys.argv) > 2: | ||
| 22 | sys.exit(usage) | ||
| 23 | |||
| 24 | if len(sys.argv) > 1: | ||
| 25 | for_comm = sys.argv[1] | ||
| 26 | |||
| 27 | syscalls = autodict() | ||
| 28 | |||
| 29 | def trace_begin(): | ||
| 30 | pass | ||
| 31 | |||
| 32 | def trace_end(): | ||
| 33 | print_error_totals() | ||
| 34 | |||
| 35 | def raw_syscalls__sys_exit(event_name, context, common_cpu, | ||
| 36 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 37 | id, ret): | ||
| 38 | if for_comm is not None: | ||
| 39 | if common_comm != for_comm: | ||
| 40 | return | ||
| 41 | |||
| 42 | if ret < 0: | ||
| 43 | try: | ||
| 44 | syscalls[common_comm][common_pid][id][ret] += 1 | ||
| 45 | except TypeError: | ||
| 46 | syscalls[common_comm][common_pid][id][ret] = 1 | ||
| 47 | |||
| 48 | def print_error_totals(): | ||
| 49 | if for_comm is not None: | ||
| 50 | print "\nsyscall errors for %s:\n\n" % (for_comm), | ||
| 51 | else: | ||
| 52 | print "\nsyscall errors:\n\n", | ||
| 53 | |||
| 54 | print "%-30s %10s\n" % ("comm [pid]", "count"), | ||
| 55 | print "%-30s %10s\n" % ("------------------------------", \ | ||
| 56 | "----------"), | ||
| 57 | |||
| 58 | comm_keys = syscalls.keys() | ||
| 59 | for comm in comm_keys: | ||
| 60 | pid_keys = syscalls[comm].keys() | ||
| 61 | for pid in pid_keys: | ||
| 62 | print "\n%s [%d]\n" % (comm, pid), | ||
| 63 | id_keys = syscalls[comm][pid].keys() | ||
| 64 | for id in id_keys: | ||
| 65 | print " syscall: %-16d\n" % (id), | ||
| 66 | ret_keys = syscalls[comm][pid][id].keys() | ||
| 67 | for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True): | ||
| 68 | print " err = %-20d %10d\n" % (ret, val), | ||
diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py new file mode 100644 index 000000000000..6cafad40c296 --- /dev/null +++ b/tools/perf/scripts/python/sctop.py | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | # system call top | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # Periodically displays system-wide system call totals, broken down by | ||
| 6 | # syscall. If a [comm] arg is specified, only syscalls called by | ||
| 7 | # [comm] are displayed. If an [interval] arg is specified, the display | ||
| 8 | # will be refreshed every [interval] seconds. The default interval is | ||
| 9 | # 3 seconds. | ||
| 10 | |||
| 11 | import thread | ||
| 12 | import time | ||
| 13 | import os | ||
| 14 | import sys | ||
| 15 | |||
| 16 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
| 17 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
| 18 | |||
| 19 | from perf_trace_context import * | ||
| 20 | from Core import * | ||
| 21 | from Util import * | ||
| 22 | |||
| 23 | usage = "perf trace -s syscall-counts.py [comm] [interval]\n"; | ||
| 24 | |||
| 25 | for_comm = None | ||
| 26 | default_interval = 3 | ||
| 27 | interval = default_interval | ||
| 28 | |||
| 29 | if len(sys.argv) > 3: | ||
| 30 | sys.exit(usage) | ||
| 31 | |||
| 32 | if len(sys.argv) > 2: | ||
| 33 | for_comm = sys.argv[1] | ||
| 34 | interval = int(sys.argv[2]) | ||
| 35 | elif len(sys.argv) > 1: | ||
| 36 | try: | ||
| 37 | interval = int(sys.argv[1]) | ||
| 38 | except ValueError: | ||
| 39 | for_comm = sys.argv[1] | ||
| 40 | interval = default_interval | ||
| 41 | |||
| 42 | syscalls = autodict() | ||
| 43 | |||
| 44 | def trace_begin(): | ||
| 45 | thread.start_new_thread(print_syscall_totals, (interval,)) | ||
| 46 | pass | ||
| 47 | |||
| 48 | def raw_syscalls__sys_enter(event_name, context, common_cpu, | ||
| 49 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 50 | id, args): | ||
| 51 | if for_comm is not None: | ||
| 52 | if common_comm != for_comm: | ||
| 53 | return | ||
| 54 | try: | ||
| 55 | syscalls[id] += 1 | ||
| 56 | except TypeError: | ||
| 57 | syscalls[id] = 1 | ||
| 58 | |||
| 59 | def print_syscall_totals(interval): | ||
| 60 | while 1: | ||
| 61 | clear_term() | ||
| 62 | if for_comm is not None: | ||
| 63 | print "\nsyscall events for %s:\n\n" % (for_comm), | ||
| 64 | else: | ||
| 65 | print "\nsyscall events:\n\n", | ||
| 66 | |||
| 67 | print "%-40s %10s\n" % ("event", "count"), | ||
| 68 | print "%-40s %10s\n" % ("----------------------------------------", \ | ||
| 69 | "----------"), | ||
| 70 | |||
| 71 | for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ | ||
| 72 | reverse = True): | ||
| 73 | try: | ||
| 74 | print "%-40d %10d\n" % (id, val), | ||
| 75 | except TypeError: | ||
| 76 | pass | ||
| 77 | syscalls.clear() | ||
| 78 | time.sleep(interval) | ||
diff --git a/tools/perf/scripts/python/syscall-counts-by-pid.py b/tools/perf/scripts/python/syscall-counts-by-pid.py new file mode 100644 index 000000000000..af722d6a4b3f --- /dev/null +++ b/tools/perf/scripts/python/syscall-counts-by-pid.py | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | # system call counts, by pid | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # Displays system-wide system call totals, broken down by syscall. | ||
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | ||
| 7 | |||
| 8 | import os | ||
| 9 | import sys | ||
| 10 | |||
| 11 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
| 12 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
| 13 | |||
| 14 | from perf_trace_context import * | ||
| 15 | from Core import * | ||
| 16 | |||
| 17 | usage = "perf trace -s syscall-counts-by-pid.py [comm]\n"; | ||
| 18 | |||
| 19 | for_comm = None | ||
| 20 | |||
| 21 | if len(sys.argv) > 2: | ||
| 22 | sys.exit(usage) | ||
| 23 | |||
| 24 | if len(sys.argv) > 1: | ||
| 25 | for_comm = sys.argv[1] | ||
| 26 | |||
| 27 | syscalls = autodict() | ||
| 28 | |||
| 29 | def trace_begin(): | ||
| 30 | pass | ||
| 31 | |||
| 32 | def trace_end(): | ||
| 33 | print_syscall_totals() | ||
| 34 | |||
| 35 | def raw_syscalls__sys_enter(event_name, context, common_cpu, | ||
| 36 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 37 | id, args): | ||
| 38 | if for_comm is not None: | ||
| 39 | if common_comm != for_comm: | ||
| 40 | return | ||
| 41 | try: | ||
| 42 | syscalls[common_comm][common_pid][id] += 1 | ||
| 43 | except TypeError: | ||
| 44 | syscalls[common_comm][common_pid][id] = 1 | ||
| 45 | |||
| 46 | def print_syscall_totals(): | ||
| 47 | if for_comm is not None: | ||
| 48 | print "\nsyscall events for %s:\n\n" % (for_comm), | ||
| 49 | else: | ||
| 50 | print "\nsyscall events by comm/pid:\n\n", | ||
| 51 | |||
| 52 | print "%-40s %10s\n" % ("comm [pid]/syscalls", "count"), | ||
| 53 | print "%-40s %10s\n" % ("----------------------------------------", \ | ||
| 54 | "----------"), | ||
| 55 | |||
| 56 | comm_keys = syscalls.keys() | ||
| 57 | for comm in comm_keys: | ||
| 58 | pid_keys = syscalls[comm].keys() | ||
| 59 | for pid in pid_keys: | ||
| 60 | print "\n%s [%d]\n" % (comm, pid), | ||
| 61 | id_keys = syscalls[comm][pid].keys() | ||
| 62 | for id, val in sorted(syscalls[comm][pid].iteritems(), \ | ||
| 63 | key = lambda(k, v): (v, k), reverse = True): | ||
| 64 | print " %-38d %10d\n" % (id, val), | ||
diff --git a/tools/perf/scripts/python/syscall-counts.py b/tools/perf/scripts/python/syscall-counts.py new file mode 100644 index 000000000000..f977e85ff049 --- /dev/null +++ b/tools/perf/scripts/python/syscall-counts.py | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | # system call counts | ||
| 2 | # (c) 2010, Tom Zanussi <tzanussi@gmail.com> | ||
| 3 | # Licensed under the terms of the GNU GPL License version 2 | ||
| 4 | # | ||
| 5 | # Displays system-wide system call totals, broken down by syscall. | ||
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | ||
| 7 | |||
| 8 | import os | ||
| 9 | import sys | ||
| 10 | |||
| 11 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
| 12 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
| 13 | |||
| 14 | from perf_trace_context import * | ||
| 15 | from Core import * | ||
| 16 | |||
| 17 | usage = "perf trace -s syscall-counts.py [comm]\n"; | ||
| 18 | |||
| 19 | for_comm = None | ||
| 20 | |||
| 21 | if len(sys.argv) > 2: | ||
| 22 | sys.exit(usage) | ||
| 23 | |||
| 24 | if len(sys.argv) > 1: | ||
| 25 | for_comm = sys.argv[1] | ||
| 26 | |||
| 27 | syscalls = autodict() | ||
| 28 | |||
| 29 | def trace_begin(): | ||
| 30 | pass | ||
| 31 | |||
| 32 | def trace_end(): | ||
| 33 | print_syscall_totals() | ||
| 34 | |||
| 35 | def raw_syscalls__sys_enter(event_name, context, common_cpu, | ||
| 36 | common_secs, common_nsecs, common_pid, common_comm, | ||
| 37 | id, args): | ||
| 38 | if for_comm is not None: | ||
| 39 | if common_comm != for_comm: | ||
| 40 | return | ||
| 41 | try: | ||
| 42 | syscalls[id] += 1 | ||
| 43 | except TypeError: | ||
| 44 | syscalls[id] = 1 | ||
| 45 | |||
| 46 | def print_syscall_totals(): | ||
| 47 | if for_comm is not None: | ||
| 48 | print "\nsyscall events for %s:\n\n" % (for_comm), | ||
| 49 | else: | ||
| 50 | print "\nsyscall events:\n\n", | ||
| 51 | |||
| 52 | print "%-40s %10s\n" % ("event", "count"), | ||
| 53 | print "%-40s %10s\n" % ("----------------------------------------", \ | ||
| 54 | "-----------"), | ||
| 55 | |||
| 56 | for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ | ||
| 57 | reverse = True): | ||
| 58 | print "%-40d %10d\n" % (id, val), | ||
