2019-05-27 09:55:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-01-27 11:27:55 +03:00
/*
* trace - event - scripting . Scripting engine common and initialization code .
*
* Copyright ( C ) 2009 - 2010 Tom Zanussi < tzanussi @ gmail . com >
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <errno.h>
2023-03-15 11:43:21 +03:00
# ifdef HAVE_LIBTRACEEVENT
perf build: Use libtraceevent from the system
Remove the LIBTRACEEVENT_DYNAMIC and LIBTRACEFS_DYNAMIC make command
line variables.
If libtraceevent isn't installed or NO_LIBTRACEEVENT=1 is passed to the
build, don't compile in libtraceevent and libtracefs support.
This also disables CONFIG_TRACE that controls "perf trace".
CONFIG_LIBTRACEEVENT is used to control enablement in Build/Makefiles,
HAVE_LIBTRACEEVENT is used in C code.
Without HAVE_LIBTRACEEVENT tracepoints are disabled and as such the
commands kmem, kwork, lock, sched and timechart are removed. The
majority of commands continue to work including "perf test".
Committer notes:
Fixed up a tools/perf/util/Build reject and added:
#include <traceevent/event-parse.h>
to tools/perf/util/scripting-engines/trace-event-perl.c.
Committer testing:
$ rpm -qi libtraceevent-devel
Name : libtraceevent-devel
Version : 1.5.3
Release : 2.fc36
Architecture: x86_64
Install Date: Mon 25 Jul 2022 03:20:19 PM -03
Group : Unspecified
Size : 27728
License : LGPLv2+ and GPLv2+
Signature : RSA/SHA256, Fri 15 Apr 2022 02:11:58 PM -03, Key ID 999f7cbf38ab71f4
Source RPM : libtraceevent-1.5.3-2.fc36.src.rpm
Build Date : Fri 15 Apr 2022 10:57:01 AM -03
Build Host : buildvm-x86-05.iad2.fedoraproject.org
Packager : Fedora Project
Vendor : Fedora Project
URL : https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/
Bug URL : https://bugz.fedoraproject.org/libtraceevent
Summary : Development headers of libtraceevent
Description :
Development headers of libtraceevent-libs
$
Default build:
$ ldd ~/bin/perf | grep tracee
libtraceevent.so.1 => /lib64/libtraceevent.so.1 (0x00007f1dcaf8f000)
$
# perf trace -e sched:* --max-events 10
0.000 migration/0/17 sched:sched_migrate_task(comm: "", pid: 1603763 (perf), prio: 120, dest_cpu: 1)
0.005 migration/0/17 sched:sched_wake_idle_without_ipi(cpu: 1)
0.011 migration/0/17 sched:sched_switch(prev_comm: "", prev_pid: 17 (migration/0), prev_state: 1, next_comm: "", next_prio: 120)
1.173 :0/0 sched:sched_wakeup(comm: "", pid: 3138 (gnome-terminal-), prio: 120)
1.180 :0/0 sched:sched_switch(prev_comm: "", prev_prio: 120, next_comm: "", next_pid: 3138 (gnome-terminal-), next_prio: 120)
0.156 migration/1/21 sched:sched_migrate_task(comm: "", pid: 1603763 (perf), prio: 120, orig_cpu: 1, dest_cpu: 2)
0.160 migration/1/21 sched:sched_wake_idle_without_ipi(cpu: 2)
0.166 migration/1/21 sched:sched_switch(prev_comm: "", prev_pid: 21 (migration/1), prev_state: 1, next_comm: "", next_prio: 120)
1.183 :0/0 sched:sched_wakeup(comm: "", pid: 1602985 (kworker/u16:0-f), prio: 120, target_cpu: 1)
1.186 :0/0 sched:sched_switch(prev_comm: "", prev_prio: 120, next_comm: "", next_pid: 1602985 (kworker/u16:0-f), next_prio: 120)
#
Had to tweak tools/perf/util/setup.py to make sure the python binding
shared object links with libtraceevent if -DHAVE_LIBTRACEEVENT is
present in CFLAGS.
Building with NO_LIBTRACEEVENT=1 uncovered some more build failures:
- Make building of data-convert-bt.c to CONFIG_LIBTRACEEVENT=y
- perf-$(CONFIG_LIBTRACEEVENT) += scripts/
- bpf_kwork.o needs also to be dependent on CONFIG_LIBTRACEEVENT=y
- The python binding needed some fixups and util/trace-event.c can't be
built and linked with the python binding shared object, so remove it
in tools/perf/util/setup.py and exclude it from the list of
dependencies in the python/perf.so Makefile.perf target.
Building without libtraceevent-devel installed uncovered more build
failures:
- The python binding tools/perf/util/python.c was assuming that
traceevent/parse-events.h was always available, which was the case
when we defaulted to using the in-kernel tools/lib/traceevent/ files,
now we need to enclose it under ifdef HAVE_LIBTRACEEVENT, just like
the other parts of it that deal with tracepoints.
- We have to ifdef the rules in the Build files with
CONFIG_LIBTRACEEVENT=y to build builtin-trace.c and
tools/perf/trace/beauty/ as we only ifdef setting CONFIG_TRACE=y when
setting NO_LIBTRACEEVENT=1 in the make command line, not when we don't
detect libtraceevent-devel installed in the system. Simplification here
to avoid these two ways of disabling builtin-trace.c and not having
CONFIG_TRACE=y when libtraceevent-devel isn't installed is the clean
way.
From Athira:
<quote>
tools/perf/arch/powerpc/util/Build
-perf-y += kvm-stat.o
+perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
</quote>
Then, ditto for arm64 and s390, detected by container cross build tests.
- s/390 uses test__checkevent_tracepoint() that is now only available if
HAVE_LIBTRACEEVENT is defined, enclose the callsite with ifder HAVE_LIBTRACEEVENT.
Also from Athira:
<quote>
With this change, I could successfully compile in these environment:
- Without libtraceevent-devel installed
- With libtraceevent-devel installed
- With “make NO_LIBTRACEEVENT=1”
</quote>
Then, finally rename CONFIG_TRACEEVENT to CONFIG_LIBTRACEEVENT for
consistency with other libraries detected in tools/perf/.
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: bpf@vger.kernel.org
Link: http://lore.kernel.org/lkml/20221205225940.3079667-3-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2022-12-06 01:59:39 +03:00
# include <traceevent/event-parse.h>
2023-03-15 11:43:21 +03:00
# endif
2010-01-27 11:27:55 +03:00
2016-10-25 23:30:05 +03:00
# include "debug.h"
2010-01-27 11:27:55 +03:00
# include "trace-event.h"
2021-05-30 22:22:58 +03:00
# include "evsel.h"
2019-07-04 17:32:27 +03:00
# include <linux/zalloc.h>
2022-10-26 23:24:27 +03:00
# include "util/sample.h"
2010-01-27 11:27:55 +03:00
struct scripting_context * scripting_context ;
2021-05-30 22:22:58 +03:00
void scripting_context__update ( struct scripting_context * c ,
union perf_event * event ,
struct perf_sample * sample ,
struct evsel * evsel ,
struct addr_location * al ,
struct addr_location * addr_al )
{
c - > event_data = sample - > raw_data ;
2023-03-15 11:43:21 +03:00
c - > pevent = NULL ;
# ifdef HAVE_LIBTRACEEVENT
2021-05-30 22:22:58 +03:00
if ( evsel - > tp_format )
c - > pevent = evsel - > tp_format - > tep ;
2023-03-15 11:43:21 +03:00
# endif
2021-05-30 22:22:58 +03:00
c - > event = event ;
c - > sample = sample ;
c - > evsel = evsel ;
c - > al = al ;
c - > addr_al = addr_al ;
}
2014-08-15 23:08:37 +04:00
static int flush_script_unsupported ( void )
{
return 0 ;
}
2010-01-27 11:27:55 +03:00
static int stop_script_unsupported ( void )
{
return 0 ;
}
2012-09-11 02:15:03 +04:00
static void process_event_unsupported ( union perf_event * event __maybe_unused ,
struct perf_sample * sample __maybe_unused ,
2019-07-21 14:23:51 +03:00
struct evsel * evsel __maybe_unused ,
2021-05-25 12:51:05 +03:00
struct addr_location * al __maybe_unused ,
struct addr_location * addr_al __maybe_unused )
2010-01-27 11:27:55 +03:00
{
}
2010-01-27 11:27:57 +03:00
static void print_python_unsupported_msg ( void )
{
fprintf ( stderr , " Python scripting not supported. "
" Install libpython and rebuild perf to enable it. \n "
" For example: \n # apt-get install python-dev (ubuntu) "
" \n # yum install python-devel (Fedora) "
" \n etc. \n " ) ;
}
2012-09-11 02:15:03 +04:00
static int python_start_script_unsupported ( const char * script __maybe_unused ,
int argc __maybe_unused ,
2021-05-30 22:22:59 +03:00
const char * * argv __maybe_unused ,
struct perf_session * session __maybe_unused )
2010-01-27 11:27:57 +03:00
{
print_python_unsupported_msg ( ) ;
return - 1 ;
}
2018-08-08 21:02:46 +03:00
static int python_generate_script_unsupported ( struct tep_handle * pevent
2012-09-11 02:15:03 +04:00
__maybe_unused ,
const char * outfile
__maybe_unused )
2010-01-27 11:27:57 +03:00
{
print_python_unsupported_msg ( ) ;
return - 1 ;
}
struct scripting_ops python_scripting_unsupported_ops = {
. name = " Python " ,
2021-05-24 09:57:18 +03:00
. dirname = " python " ,
2010-01-27 11:27:57 +03:00
. start_script = python_start_script_unsupported ,
2014-08-15 23:08:37 +04:00
. flush_script = flush_script_unsupported ,
2010-01-27 11:27:57 +03:00
. stop_script = stop_script_unsupported ,
. process_event = process_event_unsupported ,
. generate_script = python_generate_script_unsupported ,
} ;
static void register_python_scripting ( struct scripting_ops * scripting_ops )
{
2016-10-25 23:20:47 +03:00
if ( scripting_context = = NULL )
scripting_context = malloc ( sizeof ( * scripting_context ) ) ;
2016-10-25 23:30:05 +03:00
if ( scripting_context = = NULL | |
script_spec_register ( " Python " , scripting_ops ) | |
script_spec_register ( " py " , scripting_ops ) ) {
pr_err ( " Error registering Python script extension: disabling it \n " ) ;
zfree ( & scripting_context ) ;
}
2010-01-27 11:27:57 +03:00
}
2018-04-09 13:26:47 +03:00
# ifndef HAVE_LIBPYTHON_SUPPORT
2010-01-27 11:27:57 +03:00
void setup_python_scripting ( void )
{
register_python_scripting ( & python_scripting_unsupported_ops ) ;
}
# else
2010-09-21 02:45:01 +04:00
extern struct scripting_ops python_scripting_ops ;
2010-01-27 11:27:57 +03:00
void setup_python_scripting ( void )
{
register_python_scripting ( & python_scripting_ops ) ;
}
# endif
2023-03-15 11:43:21 +03:00
# ifdef HAVE_LIBTRACEEVENT
2010-01-27 11:27:55 +03:00
static void print_perl_unsupported_msg ( void )
{
fprintf ( stderr , " Perl scripting not supported. "
" Install libperl and rebuild perf to enable it. \n "
" For example: \n # apt-get install libperl-dev (ubuntu) "
" \n # yum install 'perl(ExtUtils::Embed)' (Fedora) "
" \n etc. \n " ) ;
}
2012-09-11 02:15:03 +04:00
static int perl_start_script_unsupported ( const char * script __maybe_unused ,
int argc __maybe_unused ,
2021-05-30 22:22:59 +03:00
const char * * argv __maybe_unused ,
struct perf_session * session __maybe_unused )
2010-01-27 11:27:55 +03:00
{
print_perl_unsupported_msg ( ) ;
return - 1 ;
}
2018-08-08 21:02:46 +03:00
static int perl_generate_script_unsupported ( struct tep_handle * pevent
2012-09-11 02:15:03 +04:00
__maybe_unused ,
const char * outfile __maybe_unused )
2010-01-27 11:27:55 +03:00
{
print_perl_unsupported_msg ( ) ;
return - 1 ;
}
struct scripting_ops perl_scripting_unsupported_ops = {
. name = " Perl " ,
2021-05-24 09:57:18 +03:00
. dirname = " perl " ,
2010-01-27 11:27:55 +03:00
. start_script = perl_start_script_unsupported ,
2014-08-15 23:08:37 +04:00
. flush_script = flush_script_unsupported ,
2010-01-27 11:27:55 +03:00
. stop_script = stop_script_unsupported ,
. process_event = process_event_unsupported ,
. generate_script = perl_generate_script_unsupported ,
} ;
static void register_perl_scripting ( struct scripting_ops * scripting_ops )
{
2016-10-25 23:20:47 +03:00
if ( scripting_context = = NULL )
scripting_context = malloc ( sizeof ( * scripting_context ) ) ;
2016-10-25 23:30:05 +03:00
if ( scripting_context = = NULL | |
script_spec_register ( " Perl " , scripting_ops ) | |
script_spec_register ( " pl " , scripting_ops ) ) {
pr_err ( " Error registering Perl script extension: disabling it \n " ) ;
zfree ( & scripting_context ) ;
}
2010-01-27 11:27:55 +03:00
}
2018-04-09 13:26:47 +03:00
# ifndef HAVE_LIBPERL_SUPPORT
2010-01-27 11:27:55 +03:00
void setup_perl_scripting ( void )
{
register_perl_scripting ( & perl_scripting_unsupported_ops ) ;
}
# else
2010-09-21 02:45:01 +04:00
extern struct scripting_ops perl_scripting_ops ;
2010-01-27 11:27:55 +03:00
void setup_perl_scripting ( void )
{
register_perl_scripting ( & perl_scripting_ops ) ;
}
# endif
2023-03-15 11:43:21 +03:00
# endif