aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2009-11-25 02:15:50 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-28 04:04:27 -0500
commitd1b93772be78486397693fc39d3ddea3fda90105 (patch)
treefc4387cf44de336e655d03ee488a83cadde22e04 /tools/perf
parentbcefe12eff5dca6fdfa94ed85e5bee66380d5cd9 (diff)
perf trace: Add interface to access perf data from Perl handlers
The Perl scripting support for perf trace allows most of a trace event's data to be accessed directly as handler arguments, but not all of it e.g. the less common fields aren't passed in. To give scripts access to the other fields and/or any other data or metadata in the main perf executable that might be useful, a way to access the C data in perf from Perl is needed; this patch uses the Perl XS facility to do it for the common_xxx event fields not passed to handler functions. Context.pm exports three functions to Perl scripts that access fields for the current event by calling back into perf: common_pc(), common_flags() and common_lock_depth(). Support for common_flags() field values was added to Core.pm and a script used to sanity check these and other basic scripting features, check-perf-trace.pl, was also added. Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org Cc: anton@samba.org Cc: hch@infradead.org LKML-Reference: <1259133352-23685-6-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Makefile6
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Context.c134
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Context.xs41
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL11
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/README34
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm55
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm35
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/typemap1
-rw-r--r--tools/perf/scripts/perl/check-perf-trace.pl106
-rw-r--r--tools/perf/util/trace-event-parse.c6
-rw-r--r--tools/perf/util/trace-event-perl.c46
-rw-r--r--tools/perf/util/trace-event-perl.h9
-rw-r--r--tools/perf/util/trace-event.h3
13 files changed, 474 insertions, 13 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index efbc0e864212..8ad57b51d648 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -497,6 +497,7 @@ ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; e
497 BASIC_CFLAGS += -DNO_LIBPERL 497 BASIC_CFLAGS += -DNO_LIBPERL
498else 498else
499 ALL_LDFLAGS += $(PERL_EMBED_LDOPTS) 499 ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
500 LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
500endif 501endif
501 502
502ifdef NO_DEMANGLE 503ifdef NO_DEMANGLE
@@ -873,6 +874,9 @@ util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
873util/trace-event-perl.o: util/trace-event-perl.c PERF-CFLAGS 874util/trace-event-perl.o: util/trace-event-perl.c PERF-CFLAGS
874 $(QUIET_CC)$(CC) -o util/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter $< 875 $(QUIET_CC)$(CC) -o util/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter $<
875 876
877scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS
878 $(QUIET_CC)$(CC) -o scripts/perl/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
879
876perf-%$X: %.o $(PERFLIBS) 880perf-%$X: %.o $(PERFLIBS)
877 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) 881 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
878 882
@@ -1072,7 +1076,7 @@ distclean: clean
1072# $(RM) configure 1076# $(RM) configure
1073 1077
1074clean: 1078clean:
1075 $(RM) *.o */*.o $(LIB_FILE) 1079 $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
1076 $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X 1080 $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
1077 $(RM) $(TEST_PROGRAMS) 1081 $(RM) $(TEST_PROGRAMS)
1078 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope* 1082 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
new file mode 100644
index 000000000000..3ba3ffc54164
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
@@ -0,0 +1,134 @@
1/*
2 * This file was generated automatically by ExtUtils::ParseXS version 2.18_02 from the
3 * contents of Context.xs. Do not edit this file, edit Context.xs instead.
4 *
5 * ANY CHANGES MADE HERE WILL BE LOST!
6 *
7 */
8
9#line 1 "Context.xs"
10/*
11 * Context.xs. XS interfaces for perf trace.
12 *
13 * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include "EXTERN.h"
32#include "perl.h"
33#include "XSUB.h"
34#include "../../../util/trace-event-perl.h"
35
36#ifndef PERL_UNUSED_VAR
37# define PERL_UNUSED_VAR(var) if (0) var = var
38#endif
39
40#line 41 "Context.c"
41
42XS(XS_Perf__Trace__Context_get_common_pc); /* prototype to pass -Wmissing-prototypes */
43XS(XS_Perf__Trace__Context_get_common_pc)
44{
45#ifdef dVAR
46 dVAR; dXSARGS;
47#else
48 dXSARGS;
49#endif
50 if (items != 1)
51 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::get_common_pc", "context");
52 PERL_UNUSED_VAR(cv); /* -W */
53 {
54 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
55 int RETVAL;
56 dXSTARG;
57
58 RETVAL = get_common_pc(context);
59 XSprePUSH; PUSHi((IV)RETVAL);
60 }
61 XSRETURN(1);
62}
63
64
65XS(XS_Perf__Trace__Context_get_common_flags); /* prototype to pass -Wmissing-prototypes */
66XS(XS_Perf__Trace__Context_get_common_flags)
67{
68#ifdef dVAR
69 dVAR; dXSARGS;
70#else
71 dXSARGS;
72#endif
73 if (items != 1)
74 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::get_common_flags", "context");
75 PERL_UNUSED_VAR(cv); /* -W */
76 {
77 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
78 int RETVAL;
79 dXSTARG;
80
81 RETVAL = get_common_flags(context);
82 XSprePUSH; PUSHi((IV)RETVAL);
83 }
84 XSRETURN(1);
85}
86
87
88XS(XS_Perf__Trace__Context_get_common_lock_depth); /* prototype to pass -Wmissing-prototypes */
89XS(XS_Perf__Trace__Context_get_common_lock_depth)
90{
91#ifdef dVAR
92 dVAR; dXSARGS;
93#else
94 dXSARGS;
95#endif
96 if (items != 1)
97 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::get_common_lock_depth", "context");
98 PERL_UNUSED_VAR(cv); /* -W */
99 {
100 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
101 int RETVAL;
102 dXSTARG;
103
104 RETVAL = get_common_lock_depth(context);
105 XSprePUSH; PUSHi((IV)RETVAL);
106 }
107 XSRETURN(1);
108}
109
110#ifdef __cplusplus
111extern "C"
112#endif
113XS(boot_Perf__Trace__Context); /* prototype to pass -Wmissing-prototypes */
114XS(boot_Perf__Trace__Context)
115{
116#ifdef dVAR
117 dVAR; dXSARGS;
118#else
119 dXSARGS;
120#endif
121 const char* file = __FILE__;
122
123 PERL_UNUSED_VAR(cv); /* -W */
124 PERL_UNUSED_VAR(items); /* -W */
125 XS_VERSION_BOOTCHECK ;
126
127 newXSproto("Perf::Trace::Context::get_common_pc", XS_Perf__Trace__Context_get_common_pc, file, "$");
128 newXSproto("Perf::Trace::Context::get_common_flags", XS_Perf__Trace__Context_get_common_flags, file, "$");
129 newXSproto("Perf::Trace::Context::get_common_lock_depth", XS_Perf__Trace__Context_get_common_lock_depth, file, "$");
130 if (PL_unitcheckav)
131 call_list(PL_scopestack_ix, PL_unitcheckav);
132 XSRETURN_YES;
133}
134
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
new file mode 100644
index 000000000000..24facb3696d4
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
@@ -0,0 +1,41 @@
1/*
2 * Context.xs. XS interfaces for perf trace.
3 *
4 * Copyright (C) 2009 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 "EXTERN.h"
23#include "perl.h"
24#include "XSUB.h"
25#include "../../../util/trace-event-perl.h"
26
27MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
28PROTOTYPES: ENABLE
29
30int
31get_common_pc(context)
32 struct scripting_context * context
33
34int
35get_common_flags(context)
36 struct scripting_context * context
37
38int
39get_common_lock_depth(context)
40 struct scripting_context * context
41
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
index b0de02e6950d..decdeb0f6789 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
@@ -3,10 +3,15 @@ use ExtUtils::MakeMaker;
3# See lib/ExtUtils/MakeMaker.pm for details of how to influence 3# See lib/ExtUtils/MakeMaker.pm for details of how to influence
4# the contents of the Makefile that is written. 4# the contents of the Makefile that is written.
5WriteMakefile( 5WriteMakefile(
6 NAME => 'Perf::Trace::Util', 6 NAME => 'Perf::Trace::Context',
7 VERSION_FROM => 'lib/Perf/Trace/Util.pm', # finds $VERSION 7 VERSION_FROM => 'lib/Perf/Trace/Context.pm', # finds $VERSION
8 PREREQ_PM => {}, # e.g., Module::Name => 1.1 8 PREREQ_PM => {}, # e.g., Module::Name => 1.1
9 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 9 ($] >= 5.005 ? ## Add these new keywords supported since 5.005
10 (ABSTRACT_FROM => 'lib/Perf/Trace/Util.pm', # retrieve abstract from module 10 (ABSTRACT_FROM => 'lib/Perf/Trace/Context.pm', # retrieve abstract from module
11 AUTHOR => 'Tom Zanussi <tzanussi@gmail.com>') : ()), 11 AUTHOR => 'Tom Zanussi <tzanussi@gmail.com>') : ()),
12 LIBS => [''], # e.g., '-lm'
13 DEFINE => '-I ../..', # e.g., '-DHAVE_SOMETHING'
14 INC => '-I.', # e.g., '-I. -I/usr/include/other'
15 # Un-comment this if you add C files to link with later:
16 OBJECT => 'Context.o', # link all the C files too
12); 17);
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/README b/tools/perf/scripts/perl/Perf-Trace-Util/README
index 0a58378f0836..adb99aa3a7b8 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/README
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/README
@@ -3,6 +3,34 @@ Perf-Trace-Util version 0.01
3 3
4This module contains utility functions for use with perf trace. 4This module contains utility functions for use with perf trace.
5 5
6Core.pm and Util.pm are pure Perl modules; Core.pm contains routines
7that the core perf support for Perl calls on and should always be
8'used', while Util.pm contains useful but optional utility functions
9that scripts may want to use. Context.pm contains the Perl->C
10interface that allows scripts to access data in the embedding perf
11executable; scripts wishing to do that should 'use Context.pm'.
12
13The Perl->C perf interface is completely driven by Context.xs. If you
14want to add new Perl functions that end up accessing C data in the
15perf executable, you add desciptions of the new functions here.
16scripting_context is a pointer to the perf data in the perf executable
17that you want to access - it's passed as the second parameter,
18$context, to all handler functions.
19
20After you do that:
21
22 perl Makefile.PL # to create a Makefile for the next step
23 make # to create Context.c
24
25 edit Context.c to add const to the char* file = __FILE__ line in
26 XS(boot_Perf__Trace__Context) to silence a warning/error.
27
28 You can delete the Makefile, object files and anything else that was
29 generated e.g. blib and shared library, etc, except for of course
30 Context.c
31
32 You should then be able to run the normal perf make as usual.
33
6INSTALLATION 34INSTALLATION
7 35
8Building perf with perf trace Perl scripting should install this 36Building perf with perf trace Perl scripting should install this
@@ -15,12 +43,10 @@ DEPENDENCIES
15 43
16This module requires these other modules and libraries: 44This module requires these other modules and libraries:
17 45
18 blah blah blah 46 None
19 47
20COPYRIGHT AND LICENCE 48COPYRIGHT AND LICENCE
21 49
22Put the correct copyright and licence information here.
23
24Copyright (C) 2009 by Tom Zanussi <tzanussi@gmail.com> 50Copyright (C) 2009 by Tom Zanussi <tzanussi@gmail.com>
25 51
26This library is free software; you can redistribute it and/or modify 52This library is free software; you can redistribute it and/or modify
@@ -31,5 +57,3 @@ Alternatively, this software may be distributed under the terms of the
31GNU General Public License ("GPL") version 2 as published by the Free 57GNU General Public License ("GPL") version 2 as published by the Free
32Software Foundation. 58Software Foundation.
33 59
34
35
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
new file mode 100644
index 000000000000..6c7f3659cb17
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
@@ -0,0 +1,55 @@
1package Perf::Trace::Context;
2
3use 5.010000;
4use strict;
5use warnings;
6
7require Exporter;
8
9our @ISA = qw(Exporter);
10
11our %EXPORT_TAGS = ( 'all' => [ qw(
12) ] );
13
14our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
15
16our @EXPORT = qw(
17 common_pc common_flags common_lock_depth
18);
19
20our $VERSION = '0.01';
21
22require XSLoader;
23XSLoader::load('Perf::Trace::Context', $VERSION);
24
251;
26__END__
27=head1 NAME
28
29Perf::Trace::Context - Perl extension for accessing functions in perf.
30
31=head1 SYNOPSIS
32
33 use Perf::Trace::Context;
34
35=head1 SEE ALSO
36
37Perf (trace) documentation
38
39=head1 AUTHOR
40
41Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
42
43=head1 COPYRIGHT AND LICENSE
44
45Copyright (C) 2009 by Tom Zanussi
46
47This library is free software; you can redistribute it and/or modify
48it under the same terms as Perl itself, either Perl version 5.10.0 or,
49at your option, any later version of Perl 5 you may have available.
50
51Alternatively, this software may be distributed under the terms of the
52GNU General Public License ("GPL") version 2 as published by the Free
53Software Foundation.
54
55=cut
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
index fd250fb7be16..9df376a9f629 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
@@ -16,10 +16,45 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
16our @EXPORT = qw( 16our @EXPORT = qw(
17define_flag_field define_flag_value flag_str dump_flag_fields 17define_flag_field define_flag_value flag_str dump_flag_fields
18define_symbolic_field define_symbolic_value symbol_str dump_symbolic_fields 18define_symbolic_field define_symbolic_value symbol_str dump_symbolic_fields
19trace_flag_str
19); 20);
20 21
21our $VERSION = '0.01'; 22our $VERSION = '0.01';
22 23
24my %trace_flags = (0x00 => "NONE",
25 0x01 => "IRQS_OFF",
26 0x02 => "IRQS_NOSUPPORT",
27 0x04 => "NEED_RESCHED",
28 0x08 => "HARDIRQ",
29 0x10 => "SOFTIRQ");
30
31sub trace_flag_str
32{
33 my ($value) = @_;
34
35 my $string;
36
37 my $print_delim = 0;
38
39 foreach my $idx (sort {$a <=> $b} keys %trace_flags) {
40 if (!$value && !$idx) {
41 $string .= "NONE";
42 last;
43 }
44
45 if ($idx && ($value & $idx) == $idx) {
46 if ($print_delim) {
47 $string .= " | ";
48 }
49 $string .= "$trace_flags{$idx}";
50 $print_delim = 1;
51 $value &= ~$idx;
52 }
53 }
54
55 return $string;
56}
57
23my %flag_fields; 58my %flag_fields;
24my %symbolic_fields; 59my %symbolic_fields;
25 60
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/typemap b/tools/perf/scripts/perl/Perf-Trace-Util/typemap
new file mode 100644
index 000000000000..840836804aa7
--- /dev/null
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/typemap
@@ -0,0 +1 @@
struct scripting_context * T_PTR
diff --git a/tools/perf/scripts/perl/check-perf-trace.pl b/tools/perf/scripts/perl/check-perf-trace.pl
new file mode 100644
index 000000000000..4e7dc0a407a5
--- /dev/null
+++ b/tools/perf/scripts/perl/check-perf-trace.pl
@@ -0,0 +1,106 @@
1# perf trace event handlers, generated by perf trace -g perl
2# (c) 2009, 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, perl scripting support should be ok.
9
10use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
11use lib "./Perf-Trace-Util/lib";
12use Perf::Trace::Core;
13use Perf::Trace::Context;
14use Perf::Trace::Util;
15
16sub trace_begin
17{
18 print "trace_begin\n";
19}
20
21sub trace_end
22{
23 print "trace_end\n";
24
25 print_unhandled();
26}
27
28sub irq::softirq_entry
29{
30 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
31 $common_pid, $common_comm,
32 $vec) = @_;
33
34 print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
35 $common_pid, $common_comm);
36
37 print_uncommon($context);
38
39 printf("vec=%s\n",
40 symbol_str("irq::softirq_entry", "vec", $vec));
41}
42
43sub kmem::kmalloc
44{
45 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
46 $common_pid, $common_comm,
47 $call_site, $ptr, $bytes_req, $bytes_alloc,
48 $gfp_flags) = @_;
49
50 print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
51 $common_pid, $common_comm);
52
53 print_uncommon($context);
54
55 printf("call_site=%p, ptr=%p, bytes_req=%u, bytes_alloc=%u, ".
56 "gfp_flags=%s\n",
57 $call_site, $ptr, $bytes_req, $bytes_alloc,
58
59 flag_str("kmem::kmalloc", "gfp_flags", $gfp_flags));
60}
61
62# print trace fields not included in handler args
63sub print_uncommon
64{
65 my ($context) = @_;
66
67 printf("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}
72
73my %unhandled;
74
75sub print_unhandled
76{
77 if ((scalar keys %unhandled) == 0) {
78 return;
79 }
80
81 print "\nunhandled events:\n\n";
82
83 printf("%-40s %10s\n", "event", "count");
84 printf("%-40s %10s\n", "----------------------------------------",
85 "-----------");
86
87 foreach my $event_name (keys %unhandled) {
88 printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
89 }
90}
91
92sub trace_unhandled
93{
94 my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
95 $common_pid, $common_comm) = @_;
96
97 $unhandled{$event_name}++;
98}
99
100sub print_header
101{
102 my ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;
103
104 printf("%-20s %5u %05u.%09u %8u %-20s ",
105 $event_name, $cpu, $secs, $nsecs, $pid, $comm);
106}
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 1f16495e5597..0302405aa2ca 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1982,7 +1982,7 @@ int trace_parse_common_pid(void *data)
1982 "common_pid"); 1982 "common_pid");
1983} 1983}
1984 1984
1985static int parse_common_pc(void *data) 1985int parse_common_pc(void *data)
1986{ 1986{
1987 static int pc_offset; 1987 static int pc_offset;
1988 static int pc_size; 1988 static int pc_size;
@@ -1991,7 +1991,7 @@ static int parse_common_pc(void *data)
1991 "common_preempt_count"); 1991 "common_preempt_count");
1992} 1992}
1993 1993
1994static int parse_common_flags(void *data) 1994int parse_common_flags(void *data)
1995{ 1995{
1996 static int flags_offset; 1996 static int flags_offset;
1997 static int flags_size; 1997 static int flags_size;
@@ -2000,7 +2000,7 @@ static int parse_common_flags(void *data)
2000 "common_flags"); 2000 "common_flags");
2001} 2001}
2002 2002
2003static int parse_common_lock_depth(void *data) 2003int parse_common_lock_depth(void *data)
2004{ 2004{
2005 static int ld_offset; 2005 static int ld_offset;
2006 static int ld_size; 2006 static int ld_size;
diff --git a/tools/perf/util/trace-event-perl.c b/tools/perf/util/trace-event-perl.c
index c56b08d704da..d179adebc547 100644
--- a/tools/perf/util/trace-event-perl.c
+++ b/tools/perf/util/trace-event-perl.c
@@ -30,6 +30,21 @@
30#include "trace-event.h" 30#include "trace-event.h"
31#include "trace-event-perl.h" 31#include "trace-event-perl.h"
32 32
33void xs_init(pTHX);
34
35void boot_Perf__Trace__Context(pTHX_ CV *cv);
36void boot_DynaLoader(pTHX_ CV *cv);
37
38void xs_init(pTHX)
39{
40 const char *file = __FILE__;
41 dXSUB_SYS;
42
43 newXS("Perf::Trace::Context::bootstrap", boot_Perf__Trace__Context,
44 file);
45 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
46}
47
33INTERP my_perl; 48INTERP my_perl;
34 49
35#define FTRACE_MAX_EVENT \ 50#define FTRACE_MAX_EVENT \
@@ -227,6 +242,33 @@ static inline struct event *find_cache_event(int type)
227 return event; 242 return event;
228} 243}
229 244
245int get_common_pc(struct scripting_context *context)
246{
247 int pc;
248
249 pc = parse_common_pc(context->event_data);
250
251 return pc;
252}
253
254int get_common_flags(struct scripting_context *context)
255{
256 int flags;
257
258 flags = parse_common_flags(context->event_data);
259
260 return flags;
261}
262
263int get_common_lock_depth(struct scripting_context *context)
264{
265 int lock_depth;
266
267 lock_depth = parse_common_lock_depth(context->event_data);
268
269 return lock_depth;
270}
271
230static void perl_process_event(int cpu, void *data, 272static void perl_process_event(int cpu, void *data,
231 int size __attribute((unused)), 273 int size __attribute((unused)),
232 unsigned long long nsecs, char *comm) 274 unsigned long long nsecs, char *comm)
@@ -290,6 +332,7 @@ static void perl_process_event(int cpu, void *data,
290 } 332 }
291 333
292 PUTBACK; 334 PUTBACK;
335
293 if (get_cv(handler, 0)) 336 if (get_cv(handler, 0))
294 call_pv(handler, G_SCALAR); 337 call_pv(handler, G_SCALAR);
295 else if (get_cv("main::trace_unhandled", 0)) { 338 else if (get_cv("main::trace_unhandled", 0)) {
@@ -328,7 +371,8 @@ static int perl_start_script(const char *script)
328 my_perl = perl_alloc(); 371 my_perl = perl_alloc();
329 perl_construct(my_perl); 372 perl_construct(my_perl);
330 373
331 if (perl_parse(my_perl, NULL, 2, (char **)command_line, (char **)NULL)) 374 if (perl_parse(my_perl, xs_init, 2, (char **)command_line,
375 (char **)NULL))
332 return -1; 376 return -1;
333 377
334 perl_run(my_perl); 378 perl_run(my_perl);
diff --git a/tools/perf/util/trace-event-perl.h b/tools/perf/util/trace-event-perl.h
index 6c94fa93013d..666a864f5dda 100644
--- a/tools/perf/util/trace-event-perl.h
+++ b/tools/perf/util/trace-event-perl.h
@@ -29,6 +29,11 @@ typedef int INTERP;
29#define perl_run(a) (0) 29#define perl_run(a) (0)
30#define perl_destruct(a) (0) 30#define perl_destruct(a) (0)
31#define perl_free(a) (0) 31#define perl_free(a) (0)
32#define pTHX void
33#define CV void
34#define dXSUB_SYS
35#define pTHX_
36static inline void newXS(const char *a, void *b, const char *c) {}
32#else 37#else
33#include <EXTERN.h> 38#include <EXTERN.h>
34#include <perl.h> 39#include <perl.h>
@@ -39,4 +44,8 @@ struct scripting_context {
39 void *event_data; 44 void *event_data;
40}; 45};
41 46
47int get_common_pc(struct scripting_context *context);
48int get_common_flags(struct scripting_context *context);
49int get_common_lock_depth(struct scripting_context *context);
50
42#endif /* __PERF_TRACE_EVENT_PERL_H */ 51#endif /* __PERF_TRACE_EVENT_PERL_H */
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index b1e58d3d947d..81698d5e6503 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -246,6 +246,9 @@ extern int latency_format;
246int parse_header_page(char *buf, unsigned long size); 246int parse_header_page(char *buf, unsigned long size);
247int trace_parse_common_type(void *data); 247int trace_parse_common_type(void *data);
248int trace_parse_common_pid(void *data); 248int trace_parse_common_pid(void *data);
249int parse_common_pc(void *data);
250int parse_common_flags(void *data);
251int parse_common_lock_depth(void *data);
249struct event *trace_find_event(int id); 252struct event *trace_find_event(int id);
250struct event *trace_find_next_event(struct event *event); 253struct event *trace_find_next_event(struct event *event);
251unsigned long long read_size(void *ptr, int size); 254unsigned long long read_size(void *ptr, int size);