diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-05 15:46:18 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-05 15:46:18 -0500 |
| commit | 3fa04ecd72780da31ba8b329e148179bc24a9c7d (patch) | |
| tree | f5d462fd4aee086952d18f159f737c450ab46b3b /tools/perf/scripts/python | |
| parent | 180b62a3d837613fcac3ce89576526423926c3c3 (diff) | |
| parent | 1cda707d52e51a6cafac0aef12d2bd7052d572e6 (diff) | |
Merge branch 'writeback-for-2.6.34' into nfs-for-2.6.34
Diffstat (limited to 'tools/perf/scripts/python')
13 files changed, 495 insertions, 0 deletions
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..83e91435ed09 --- /dev/null +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py | |||
| @@ -0,0 +1,25 @@ | |||
| 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 | ||
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..f8885d389e6f --- /dev/null +++ b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -c 1 -f -a -M -R -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..1e0c0a860c87 --- /dev/null +++ b/tools/perf/scripts/python/bin/failed-syscalls-by-pid-report | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide failed syscalls, by pid | ||
| 3 | # args: [comm] | ||
| 4 | perf trace -s ~/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py $1 | ||
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..45a8c50359da --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-by-pid-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -c 1 -f -a -M -R -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..f8044d192271 --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-by-pid-report | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide syscall counts, by pid | ||
| 3 | # args: [comm] | ||
| 4 | perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts-by-pid.py $1 | ||
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..45a8c50359da --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-record | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | perf record -c 1 -f -a -M -R -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..a366aa61612f --- /dev/null +++ b/tools/perf/scripts/python/bin/syscall-counts-report | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # description: system-wide syscall counts | ||
| 3 | # args: [comm] | ||
| 4 | perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts.py $1 | ||
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..964d934395ff --- /dev/null +++ b/tools/perf/scripts/python/check-perf-trace.py | |||
| @@ -0,0 +1,83 @@ | |||
| 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, common_cpu, common_secs, common_nsecs, | ||
| 55 | common_pid, common_comm): | ||
| 56 | try: | ||
| 57 | unhandled[event_name] += 1 | ||
| 58 | except TypeError: | ||
| 59 | unhandled[event_name] = 1 | ||
| 60 | |||
| 61 | def print_header(event_name, cpu, secs, nsecs, pid, comm): | ||
| 62 | print "%-20s %5u %05u.%09u %8u %-20s " % \ | ||
| 63 | (event_name, cpu, secs, nsecs, pid, comm), | ||
| 64 | |||
| 65 | # print trace fields not included in handler args | ||
| 66 | def print_uncommon(context): | ||
| 67 | print "common_preempt_count=%d, common_flags=%s, common_lock_depth=%d, " \ | ||
| 68 | % (common_pc(context), trace_flag_str(common_flags(context)), \ | ||
| 69 | common_lock_depth(context)) | ||
| 70 | |||
| 71 | def print_unhandled(): | ||
| 72 | keys = unhandled.keys() | ||
| 73 | if not keys: | ||
| 74 | return | ||
| 75 | |||
| 76 | print "\nunhandled events:\n\n", | ||
| 77 | |||
| 78 | print "%-40s %10s\n" % ("event", "count"), | ||
| 79 | print "%-40s %10s\n" % ("----------------------------------------", \ | ||
| 80 | "-----------"), | ||
| 81 | |||
| 82 | for event_name in keys: | ||
| 83 | 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/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), | ||
