From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, alice.mei.rogers@gmail.com,
namhyung@kernel.org
Cc: adrian.hunter@intel.com, dapeng1.mi@linux.intel.com,
james.clark@linaro.org, leo.yan@linux.dev,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com
Subject: [PATCH v3 48/49] perf script: Support standalone scripts and remove embedded scripting
Date: Wed, 23 Sep 2026 11:12:11 -0700 [thread overview]
Message-ID: <20260923181213.3032038-49-irogers@google.com> (raw)
In-Reply-To: <20260923181213.3032038-1-irogers@google.com>
Refactor 'perf script' to launch standalone scripts directly via fork()
and execvp() and remove the legacy embedded Perl and Python scripting
engines:
- Remove the embedded Perl scripting engine
(util/scripting-engines/trace-event-perl.c), Perl scripts, bin
wrappers, and Trace-Util library
(scripts/perl/Perf-Trace-Util/), and script_perl.sh test.
- Remove libperl feature checks from Makefile.config, Makefile.perf,
builtin-check.c, and Documentation/perf-check.txt.
- Remove -g / --gen-script option and scripting_ops dispatch table from
builtin-script.c and trace-event-scripting.c.
- Hide the legacy -s / --script option and update script discovery in
find_script() and list_available_scripts() to prioritize the system
'python' directory over bare filenames in the current directory.
- Update the Python script shell tests (test_arm_coresight_disasm.sh,
test_task_analyzer.sh, and test_*_python.sh) to invoke scripts via
'perf script <script>' rather than running the Python interpreter
directly on the script file path.
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/build/Makefile.feature | 1 -
tools/build/feature/Makefile | 20 -
tools/build/feature/test-libperl.c | 10 -
tools/perf/Build | 1 -
tools/perf/Documentation/perf-check.txt | 1 -
tools/perf/Makefile.config | 1 -
tools/perf/Makefile.perf | 14 -
tools/perf/builtin-check.c | 1 -
tools/perf/builtin-script.c | 986 +++++++++---------
tools/perf/scripts/Build | 3 -
tools/perf/scripts/perl/Perf-Trace-Util/Build | 9 -
.../scripts/perl/Perf-Trace-Util/Context.c | 122 ---
.../scripts/perl/Perf-Trace-Util/Context.xs | 42 -
.../scripts/perl/Perf-Trace-Util/Makefile.PL | 18 -
.../perf/scripts/perl/Perf-Trace-Util/README | 59 --
.../Perf-Trace-Util/lib/Perf/Trace/Context.pm | 55 -
.../Perf-Trace-Util/lib/Perf/Trace/Core.pm | 192 ----
.../Perf-Trace-Util/lib/Perf/Trace/Util.pm | 94 --
.../perf/scripts/perl/Perf-Trace-Util/typemap | 1 -
.../scripts/perl/bin/check-perf-trace-record | 2 -
.../scripts/perl/bin/failed-syscalls-record | 3 -
.../scripts/perl/bin/failed-syscalls-report | 10 -
tools/perf/scripts/perl/bin/rw-by-file-record | 3 -
tools/perf/scripts/perl/bin/rw-by-file-report | 10 -
tools/perf/scripts/perl/bin/rw-by-pid-record | 2 -
tools/perf/scripts/perl/bin/rw-by-pid-report | 3 -
tools/perf/scripts/perl/bin/rwtop-record | 2 -
tools/perf/scripts/perl/bin/rwtop-report | 20 -
.../scripts/perl/bin/wakeup-latency-record | 6 -
.../scripts/perl/bin/wakeup-latency-report | 3 -
tools/perf/scripts/perl/check-perf-trace.pl | 106 --
tools/perf/scripts/perl/failed-syscalls.pl | 47 -
tools/perf/scripts/perl/rw-by-file.pl | 106 --
tools/perf/scripts/perl/rw-by-pid.pl | 184 ----
tools/perf/scripts/perl/rwtop.pl | 203 ----
tools/perf/scripts/perl/wakeup-latency.pl | 107 --
tools/perf/tests/make | 2 -
.../coresight/test_arm_coresight_disasm.sh | 14 +-
tools/perf/tests/shell/script_perl.sh | 102 --
.../shell/test_check_perf_trace_python.sh | 2 +-
.../shell/test_compaction_times_python.sh | 6 +-
.../test_event_analyzing_sample_python.sh | 3 +-
.../shell/test_export_to_postgresql_python.sh | 8 +-
.../shell/test_export_to_sqlite_python.sh | 4 +-
.../test_failed_syscalls_by_pid_python.sh | 7 +-
.../shell/test_failed_syscalls_python.sh | 2 +-
.../tests/shell/test_flamegraph_python.sh | 8 +-
.../shell/test_futex_contention_python.sh | 2 +-
tools/perf/tests/shell/test_gecko_python.sh | 2 +-
.../shell/test_intel_pt_events_python.sh | 2 +-
.../tests/shell/test_mem_phys_addr_python.sh | 3 +-
.../shell/test_net_dropmonitor_python.sh | 2 +-
.../tests/shell/test_netdev_times_python.sh | 2 +-
.../tests/shell/test_powerpc_hcalls_python.sh | 2 +-
.../tests/shell/test_rw_by_file_python.sh | 2 +-
.../perf/tests/shell/test_rw_by_pid_python.sh | 2 +-
tools/perf/tests/shell/test_rwtop_python.sh | 2 +-
.../shell/test_sched_migration_python.sh | 2 +-
tools/perf/tests/shell/test_sctop_python.sh | 4 +-
.../tests/shell/test_stackcollapse_python.sh | 6 +-
.../perf/tests/shell/test_stat_cpi_python.sh | 4 +-
.../test_syscall_counts_by_pid_python.sh | 7 +-
.../tests/shell/test_syscall_counts_python.sh | 4 +-
tools/perf/tests/shell/test_task_analyzer.sh | 58 +-
.../tests/shell/test_wakeup_latency_python.sh | 4 +-
tools/perf/ui/browsers/scripts.c | 161 +--
tools/perf/util/Build | 3 -
tools/perf/util/scripting-engines/Build | 5 -
.../util/scripting-engines/trace-event-perl.c | 770 --------------
tools/perf/util/trace-event-parse.c | 65 --
tools/perf/util/trace-event-scripting.c | 398 -------
tools/perf/util/trace-event.h | 72 +-
72 files changed, 579 insertions(+), 3610 deletions(-)
delete mode 100644 tools/build/feature/test-libperl.c
delete mode 100644 tools/perf/scripts/Build
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Build
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Context.c
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/README
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
delete mode 100644 tools/perf/scripts/perl/Perf-Trace-Util/typemap
delete mode 100644 tools/perf/scripts/perl/bin/check-perf-trace-record
delete mode 100644 tools/perf/scripts/perl/bin/failed-syscalls-record
delete mode 100644 tools/perf/scripts/perl/bin/failed-syscalls-report
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-file-record
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-file-report
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-pid-record
delete mode 100644 tools/perf/scripts/perl/bin/rw-by-pid-report
delete mode 100644 tools/perf/scripts/perl/bin/rwtop-record
delete mode 100644 tools/perf/scripts/perl/bin/rwtop-report
delete mode 100644 tools/perf/scripts/perl/bin/wakeup-latency-record
delete mode 100644 tools/perf/scripts/perl/bin/wakeup-latency-report
delete mode 100644 tools/perf/scripts/perl/check-perf-trace.pl
delete mode 100644 tools/perf/scripts/perl/failed-syscalls.pl
delete mode 100644 tools/perf/scripts/perl/rw-by-file.pl
delete mode 100644 tools/perf/scripts/perl/rw-by-pid.pl
delete mode 100644 tools/perf/scripts/perl/rwtop.pl
delete mode 100644 tools/perf/scripts/perl/wakeup-latency.pl
delete mode 100755 tools/perf/tests/shell/script_perl.sh
delete mode 100644 tools/perf/util/scripting-engines/Build
delete mode 100644 tools/perf/util/scripting-engines/trace-event-perl.c
delete mode 100644 tools/perf/util/trace-event-scripting.c
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 3ca7a4f5c7fd..dbef5b6c4e43 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -121,7 +121,6 @@ FEATURE_TESTS_EXTRA := \
libbfd-liberty \
libbfd-liberty-z \
libopencsd \
- libperl \
llvm \
libbpf \
libpfm4 \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 269af8e8f5cf..62f9cbf3dee9 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -31,7 +31,6 @@ FILES= \
test-libdebuginfod.bin \
test-libnuma.bin \
test-numa_num_possible_cpus.bin \
- test-libperl.bin \
test-python-module.bin \
test-libslang.bin \
test-libtraceevent.bin \
@@ -242,25 +241,6 @@ $(OUTPUT)test-libtracefs.bin:
$(OUTPUT)test-gtk4.bin:
$(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk4 2>/dev/null)
-grep-libs = $(filter -l%,$(1))
-strip-libs = $(filter-out -l%,$(1))
-
-PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
-PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
-PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
-PERL_EMBED_CCOPTS = $(shell perl -MExtUtils::Embed -e ccopts 2>/dev/null)
-FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
-
-ifeq ($(CC_NO_CLANG), 0)
- PERL_EMBED_LDOPTS := $(filter-out -specs=%,$(PERL_EMBED_LDOPTS))
- PERL_EMBED_CCOPTS := $(filter-out -flto=auto -ffat-lto-objects, $(PERL_EMBED_CCOPTS))
- PERL_EMBED_CCOPTS := $(filter-out -specs=%,$(PERL_EMBED_CCOPTS))
- FLAGS_PERL_EMBED += -Wno-compound-token-split-by-macro
-endif
-
-$(OUTPUT)test-libperl.bin:
- $(BUILD) $(FLAGS_PERL_EMBED)
-
$(OUTPUT)test-python-module.bin:
$(BUILD) $(FLAGS_PYTHON_EMBED)
diff --git a/tools/build/feature/test-libperl.c b/tools/build/feature/test-libperl.c
deleted file mode 100644
index 0415f437eb31..000000000000
--- a/tools/build/feature/test-libperl.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <EXTERN.h>
-#include <perl.h>
-
-int main(void)
-{
- perl_alloc();
-
- return 0;
-}
diff --git a/tools/perf/Build b/tools/perf/Build
index 5bd0e58d7cb0..8a0b5592a973 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -61,7 +61,6 @@ perf-util-y += arch/
perf-y += arch/
perf-test-y += arch/
perf-ui-y += ui/
-perf-util-y += scripts/
gtk-y += ui/gtk/
diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
index a80913794eb6..1406a41c5d09 100644
--- a/tools/perf/Documentation/perf-check.txt
+++ b/tools/perf/Documentation/perf-check.txt
@@ -58,7 +58,6 @@ feature::
libLLVM / HAVE_LIBLLVM_SUPPORT
libnuma / HAVE_LIBNUMA_SUPPORT
libopencsd / HAVE_CSTRACE_SUPPORT
- libperl / HAVE_LIBPERL_SUPPORT
libpfm4 / HAVE_LIBPFM
libslang / HAVE_SLANG_SUPPORT
libtraceevent / HAVE_LIBTRACEEVENT
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index e469c5ee5424..fa1d984772aa 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -1273,7 +1273,6 @@ $(call detected_var,tipdir_SQ)
$(call detected_var,srcdir_SQ)
$(call detected_var,LIBDIR)
$(call detected_var,GTK_CFLAGS)
-$(call detected_var,PERL_EMBED_CCOPTS)
$(call detected_var,PYTHON_EMBED_CCOPTS)
ifneq ($(BISON_FILE_PREFIX_MAP),)
$(call detected_var,BISON_FILE_PREFIX_MAP)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 0daac2f9e349..52f8247e01a0 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -17,7 +17,6 @@ include ../scripts/utilities.mak
#
# Define CROSS_COMPILE as prefix name of compiler if you want cross-builds.
#
-# Define LIBPERL to enable perl script extension.
#
# Define NO_PYTHON_MODULE to disable python script extension.
#
@@ -486,11 +485,6 @@ OTHER_PROGRAMS = $(OUTPUT)perf
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
endif
-ifndef PERL_PATH
- PERL_PATH = /usr/bin/perl
-endif
-
-export PERL_PATH
LIBPERF_BENCH_IN := $(OUTPUT)perf-bench-in.o
LIBPERF_BENCH := $(OUTPUT)libperf-bench.a
@@ -895,14 +889,6 @@ endif
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(call QUIET_INSTALL, perf-iostat) \
$(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-ifdef LIBPERL
- $(call QUIET_INSTALL, perl-scripts) \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
- $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
- $(INSTALL) scripts/perl/*.pl -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \
- $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
-endif
ifndef NO_PYTHON_MODULE
$(call QUIET_INSTALL, python-scripts) \
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 06711362d37f..1e43e097e7a7 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -51,7 +51,6 @@ struct feature_status supported_features[] = {
FEATURE_STATUS("libLLVM", HAVE_LIBLLVM_SUPPORT),
FEATURE_STATUS("libnuma", HAVE_LIBNUMA_SUPPORT),
FEATURE_STATUS("libopencsd", HAVE_CSTRACE_SUPPORT),
- FEATURE_STATUS_TIP("libperl", HAVE_LIBPERL_SUPPORT, "Deprecated, use LIBPERL=1 and install perl-ExtUtils-Embed/libperl-dev to build with it"),
FEATURE_STATUS("python-module", HAVE_PYTHON_MODULE_SUPPORT),
FEATURE_STATUS("libpfm4", HAVE_LIBPFM),
FEATURE_STATUS("libslang", HAVE_SLANG_SUPPORT),
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 0174489d1c0f..cd2846ce03ce 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1,8 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <inttypes.h>
+#include <limits.h>
#include <signal.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
#include <dirent.h>
#include <fcntl.h>
@@ -18,6 +22,7 @@
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <sys/utsname.h>
#include <unistd.h>
@@ -77,8 +82,7 @@
#include <event-parse.h>
#endif
-static char const *script_name;
-static char const *generate_script_lang;
+static char *script_name;
static bool reltime;
static bool deltatime;
static u64 initial_time;
@@ -88,7 +92,6 @@ static u64 last_timestamp;
static u64 nr_unordered;
static bool no_callchain;
static bool latency_format;
-static bool system_wide;
static bool print_flags;
static const char *cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
@@ -96,6 +99,7 @@ static int max_blocks;
static struct dlfilter *dlfilter;
static int dlargc;
static char **dlargv;
+static unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
enum perf_output_field {
PERF_OUTPUT_COMM = 1ULL << 0,
@@ -1810,6 +1814,144 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample,
return printed;
}
+#define SAMPLE_FLAGS_BUF_SIZE 64
+#define SAMPLE_FLAGS_STR_ALIGNED_SIZE 21
+
+static int sample_flags_to_name(u32 flags, char *str, size_t size)
+{
+ static const struct {
+ u32 flags;
+ const char *name;
+ } sample_flags[] = {
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
+ {PERF_IP_FLAG_BRANCH, "jmp"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL |
+ PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT,
+ "hw int"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"},
+ {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"},
+ {0, NULL}
+ };
+ static const struct {
+ u32 flags;
+ const char *name;
+ } branch_events[] = {
+ {PERF_IP_FLAG_BRANCH_MISS, "miss"},
+ {PERF_IP_FLAG_NOT_TAKEN, "not_taken"},
+ {0, NULL}
+ };
+ int i;
+ const char *prefix;
+ int pos = 0, ret, ev_idx = 0;
+ u32 xf = flags & PERF_ADDITIONAL_STATE_MASK;
+ u32 types, events;
+ char xs[16] = { 0 };
+
+ /* Clear additional state bits */
+ flags &= ~PERF_ADDITIONAL_STATE_MASK;
+
+ if (flags & PERF_IP_FLAG_TRACE_BEGIN)
+ prefix = "tr strt ";
+ else if (flags & PERF_IP_FLAG_TRACE_END)
+ prefix = "tr end ";
+ else
+ prefix = "";
+
+ ret = snprintf(str + pos, size - pos, "%s", prefix);
+ if (ret < 0)
+ return ret;
+ pos += ret;
+
+ flags &= ~(PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END);
+
+ types = flags & ~PERF_IP_FLAG_BRANCH_EVENT_MASK;
+ for (i = 0; sample_flags[i].name; i++) {
+ if (sample_flags[i].flags != types)
+ continue;
+
+ ret = snprintf(str + pos, size - pos, "%s", sample_flags[i].name);
+ if (ret < 0)
+ return ret;
+ pos += ret;
+ break;
+ }
+
+ events = flags & PERF_IP_FLAG_BRANCH_EVENT_MASK;
+ for (i = 0; branch_events[i].name; i++) {
+ if (!(branch_events[i].flags & events))
+ continue;
+
+ ret = snprintf(str + pos, size - pos, !ev_idx ? "/%s" : ",%s",
+ branch_events[i].name);
+ if (ret < 0)
+ return ret;
+ pos += ret;
+ ev_idx++;
+ }
+
+ /* Add an end character '/' for events */
+ if (ev_idx) {
+ ret = snprintf(str + pos, size - pos, "/");
+ if (ret < 0)
+ return ret;
+ pos += ret;
+ }
+
+ if (!xf)
+ return pos;
+
+ snprintf(xs, sizeof(xs), "(%s%s%s)",
+ flags & PERF_IP_FLAG_IN_TX ? "x" : "",
+ flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "",
+ flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : "");
+
+ /* Right align the string if its length is less than the limit */
+ if ((pos + strlen(xs)) < SAMPLE_FLAGS_STR_ALIGNED_SIZE)
+ ret = snprintf(str + pos, size - pos, "%*s",
+ (int)(SAMPLE_FLAGS_STR_ALIGNED_SIZE - ret), xs);
+ else
+ ret = snprintf(str + pos, size - pos, " %s", xs);
+ if (ret < 0)
+ return ret;
+
+ return pos + ret;
+}
+
+static int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)
+{
+ const char *chars = PERF_IP_FLAG_CHARS;
+ const size_t n = strlen(PERF_IP_FLAG_CHARS);
+ size_t i, pos = 0;
+ int ret;
+
+ ret = sample_flags_to_name(flags, str, sz);
+ if (ret > 0)
+ return ret;
+
+ for (i = 0; i < n; i++, flags >>= 1) {
+ if ((flags & 1) && pos < sz)
+ str[pos++] = chars[i];
+ }
+ for (; i < 32; i++, flags >>= 1) {
+ if ((flags & 1) && pos < sz)
+ str[pos++] = '?';
+ }
+ if (pos < sz)
+ str[pos] = 0;
+
+ return pos;
+}
+
static int perf_sample__fprintf_flags(u32 flags, FILE *fp)
{
char str[SAMPLE_FLAGS_BUF_SIZE];
@@ -2653,8 +2795,6 @@ static void process_event(struct perf_script *script,
fflush(fp);
}
-static struct scripting_ops *scripting_ops;
-
static void __process_stat(struct evsel *counter, u64 tstamp)
{
int nthreads = perf_thread_map__nr(counter->core.threads);
@@ -2689,36 +2829,11 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
static void process_stat(struct evsel *counter, u64 tstamp)
{
- if (scripting_ops && scripting_ops->process_stat)
- scripting_ops->process_stat(&stat_config, counter, tstamp);
- else
- __process_stat(counter, tstamp);
-}
-
-static void process_stat_interval(u64 tstamp)
-{
- if (scripting_ops && scripting_ops->process_stat_interval)
- scripting_ops->process_stat_interval(tstamp);
-}
-
-static void setup_scripting(void)
-{
-#ifdef HAVE_LIBTRACEEVENT
- setup_perl_scripting();
-#endif
- setup_python_scripting();
+ __process_stat(counter, tstamp);
}
-static int flush_scripting(void)
+static void process_stat_interval(u64 tstamp __maybe_unused)
{
- return scripting_ops ? scripting_ops->flush_script() : 0;
-}
-
-static int cleanup_scripting(void)
-{
- pr_debug("\nperf script stopped\n");
-
- return scripting_ops ? scripting_ops->stop_script() : 0;
}
static bool filter_cpu(struct perf_sample *sample)
@@ -2793,20 +2908,7 @@ static int process_sample_event(const struct perf_tool *tool,
goto out_put;
}
- if (scripting_ops) {
- struct addr_location *addr_al_ptr = NULL;
-
- if ((evsel->core.attr.sample_type & PERF_SAMPLE_ADDR) &&
- sample_addr_correlates_sym(&evsel->core.attr)) {
- if (!addr_al.thread)
- thread__resolve(al.thread, &addr_al, sample);
- addr_al_ptr = &addr_al;
- }
- scripting_ops->process_event(event, sample, &al, addr_al_ptr);
- } else {
- process_event(scr, sample, &al, &addr_al, machine);
- }
-
+ process_event(scr, sample, &al, &addr_al, machine);
out_put:
addr_location__exit(&addr_al);
addr_location__exit(&al);
@@ -3118,9 +3220,6 @@ static int process_switch_event(const struct perf_tool *tool,
if (perf_event__process_switch(tool, event, sample, machine) < 0)
return -1;
- if (scripting_ops && scripting_ops->process_switch && !filter_cpu(sample))
- scripting_ops->process_switch(event, sample, machine);
-
if (!script->show_switch_events)
return 0;
@@ -3128,18 +3227,6 @@ static int process_switch_event(const struct perf_tool *tool,
sample->tid);
}
-static int process_auxtrace_error(const struct perf_tool *tool,
- struct perf_session *session,
- union perf_event *event)
-{
- if (scripting_ops && scripting_ops->process_auxtrace_error) {
- scripting_ops->process_auxtrace_error(session, event);
- return 0;
- }
-
- return perf_event__process_auxtrace_error(tool, session, event);
-}
-
static int
process_lost_event(const struct perf_tool *tool,
union perf_event *event,
@@ -3152,12 +3239,11 @@ process_lost_event(const struct perf_tool *tool,
static int
process_throttle_event(const struct perf_tool *tool __maybe_unused,
- union perf_event *event,
- struct perf_sample *sample,
- struct machine *machine)
+ union perf_event *event __maybe_unused,
+ struct perf_sample *sample __maybe_unused,
+ struct machine *machine __maybe_unused)
{
- if (scripting_ops && scripting_ops->process_throttle)
- scripting_ops->process_throttle(event, sample, machine);
+
return 0;
}
@@ -3300,10 +3386,9 @@ static int __cmd_script(struct perf_script *script)
script->tool.mmap = process_mmap_event;
script->tool.mmap2 = process_mmap2_event;
}
- if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch))
+ if (script->show_switch_events)
script->tool.context_switch = process_switch_event;
- if (scripting_ops && scripting_ops->process_auxtrace_error)
- script->tool.auxtrace_error = process_auxtrace_error;
+ script->tool.auxtrace_error = perf_event__process_auxtrace_error;
if (script->show_namespace_events)
script->tool.namespaces = process_namespaces_event;
if (script->show_cgroup_events)
@@ -3340,96 +3425,48 @@ static int __cmd_script(struct perf_script *script)
return ret;
}
-static int list_available_languages_cb(struct scripting_ops *ops, const char *spec)
-{
- fprintf(stderr, " %-42s [%s]\n", spec, ops->name);
- return 0;
-}
-
-static void list_available_languages(void)
-{
- fprintf(stderr, "\n");
- fprintf(stderr, "Scripting language extensions (used in "
- "perf script -s [spec:]script.[spec]):\n\n");
- script_spec__for_each(&list_available_languages_cb);
- fprintf(stderr, "\n");
-}
-
/* Find script file relative to current directory or exec path */
static char *find_script(const char *script)
{
char path[PATH_MAX];
+ char *exec_path;
- if (!scripting_ops) {
- const char *ext = strrchr(script, '.');
+ if (strchr(script, '/') && access(script, R_OK) == 0)
+ return strdup(script);
- if (!ext)
- return NULL;
+ exec_path = get_argv_exec_path();
+ if (exec_path) {
+ snprintf(path, sizeof(path), "%s/python/%s", exec_path, script);
+ if (access(path, R_OK) == 0) {
+ free(exec_path);
+ return strdup(path);
+ }
- scripting_ops = script_spec__lookup(++ext);
- if (!scripting_ops)
- return NULL;
+ snprintf(path, sizeof(path), "%s/python/%s.py", exec_path, script);
+ free(exec_path);
+ if (access(path, R_OK) == 0)
+ return strdup(path);
}
- if (access(script, R_OK)) {
- char *exec_path = get_argv_exec_path();
-
- if (!exec_path)
- return NULL;
- snprintf(path, sizeof(path), "%s/scripts/%s/%s",
- exec_path, scripting_ops->dirname, script);
- free(exec_path);
- script = path;
- if (access(script, R_OK))
- return NULL;
+ if (access(script, R_OK) == 0) {
+ if (!strchr(script, '/')) {
+ snprintf(path, sizeof(path), "./%s", script);
+ return strdup(path);
+ }
+ return strdup(script);
}
- return strdup(script);
+
+ /* Failure to find script. */
+ return NULL;
}
static int parse_scriptname(const struct option *opt __maybe_unused,
const char *str, int unset __maybe_unused)
{
- char spec[PATH_MAX];
- const char *script, *ext;
- int len;
-
- if (strcmp(str, "lang") == 0) {
- list_available_languages();
- exit(0);
- }
-
- script = strchr(str, ':');
- if (script) {
- len = script - str;
- if (len >= PATH_MAX) {
- fprintf(stderr, "invalid language specifier");
- return -1;
- }
- strncpy(spec, str, len);
- spec[len] = '\0';
- scripting_ops = script_spec__lookup(spec);
- if (!scripting_ops) {
- fprintf(stderr, "invalid language specifier");
- return -1;
- }
- script++;
- } else {
- script = str;
- ext = strrchr(script, '.');
- if (!ext) {
- fprintf(stderr, "invalid script extension");
- return -1;
- }
- scripting_ops = script_spec__lookup(++ext);
- if (!scripting_ops) {
- fprintf(stderr, "invalid script extension");
- return -1;
- }
- }
-
- script_name = find_script(script);
+ zfree(&script_name);
+ script_name = find_script(str);
if (!script_name)
- script_name = strdup(script);
+ script_name = strdup(str);
return 0;
}
@@ -3617,7 +3654,6 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
(script_dirent->d_type != DT_UNKNOWN || \
!is_directory(lang_path, script_dirent)))
-
#define RECORD_SUFFIX "-record"
#define REPORT_SUFFIX "-report"
@@ -3625,7 +3661,6 @@ struct script_desc {
struct list_head node;
char *name;
char *half_liner;
- char *args;
};
static LIST_HEAD(script_descs);
@@ -3640,16 +3675,16 @@ static struct script_desc *script_desc__new(const char *name)
return s;
}
-static void script_desc__delete(struct script_desc *s)
-{
- zfree(&s->name);
- zfree(&s->half_liner);
- zfree(&s->args);
- free(s);
-}
-
static void script_desc__add(struct script_desc *s)
{
+ struct script_desc *pos;
+
+ list_for_each_entry(pos, &script_descs, node) {
+ if (s->name && pos->name && strcasecmp(s->name, pos->name) < 0) {
+ list_add_tail(&s->node, &pos->node);
+ return;
+ }
+ }
list_add_tail(&s->node, &script_descs);
}
@@ -3697,15 +3732,65 @@ static int read_script_info(struct script_desc *desc, const char *filename)
{
char line[BUFSIZ], *p;
FILE *fp;
+ bool in_docstring = false;
+ bool found_description = false;
fp = fopen(filename, "r");
if (!fp)
return -1;
while (fgets(line, sizeof(line), fp)) {
+ static const char * const triple_quote_str[] = {
+ "\"\"\"",
+ "'''",
+ "r\"\"\"",
+ };
p = skip_spaces(line);
if (strlen(p) == 0)
continue;
+
+ if (in_docstring) {
+ if (strlen(p) && p[strlen(p) - 1] == '\n')
+ p[strlen(p) - 1] = '\0';
+ zfree(&desc->half_liner);
+ desc->half_liner = strdup(skip_spaces(p));
+ in_docstring = false;
+ found_description = true;
+ break;
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(triple_quote_str); i++) {
+ const char *quote = triple_quote_str[i];
+ const char *close_quote = quote;
+
+ if (quote[0] == 'r' || quote[0] == 'R')
+ close_quote++;
+
+ if (!strstarts(p, quote))
+ continue;
+
+ p += strlen(quote);
+ p = skip_spaces(p);
+ if (strlen(p) > 0) {
+ if (p[strlen(p) - 1] == '\n')
+ p[strlen(p) - 1] = '\0';
+ p = skip_spaces(p);
+ if (str_ends_with(p, close_quote))
+ p[strlen(p) - strlen(close_quote)] = '\0';
+ zfree(&desc->half_liner);
+ desc->half_liner = strdup(skip_spaces(p));
+ found_description = true;
+ break;
+ }
+ in_docstring = true;
+ break;
+ }
+ if (found_description)
+ break;
+
+ if (in_docstring)
+ continue;
+
if (*p != '#')
continue;
p++;
@@ -3718,14 +3803,17 @@ static int read_script_info(struct script_desc *desc, const char *filename)
if (!strncmp(p, "description:", strlen("description:"))) {
p += strlen("description:");
+ zfree(&desc->half_liner);
desc->half_liner = strdup(skip_spaces(p));
- continue;
+ found_description = true;
+ break;
}
- if (!strncmp(p, "args:", strlen("args:"))) {
- p += strlen("args:");
- desc->args = strdup(skip_spaces(p));
- continue;
+ if (!found_description && strlen(p) > 0 &&
+ strncmp(p, "SPDX-License-Identifier", 23)) {
+ if (!desc->half_liner)
+ desc->half_liner = strdup(p);
+ // Don't set found_description, maybe we find a better "description:" later!
}
}
@@ -3756,23 +3844,21 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
const char *s __maybe_unused,
int unset __maybe_unused)
{
- struct dirent *script_dirent, *lang_dirent;
- char *buf, *scripts_path, *script_path, *lang_path, *first_half;
- DIR *scripts_dir, *lang_dir;
+ struct dirent *script_dirent;
+ char *buf, *scripts_path, *script_path;
+ DIR *scripts_dir;
struct script_desc *desc;
char *script_root;
- buf = malloc(3 * MAXPATHLEN + BUFSIZ);
+ buf = malloc(2 * MAXPATHLEN + BUFSIZ);
if (!buf) {
pr_err("malloc failed\n");
exit(-1);
}
scripts_path = buf;
script_path = buf + MAXPATHLEN;
- lang_path = buf + 2 * MAXPATHLEN;
- first_half = buf + 3 * MAXPATHLEN;
- snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
+ snprintf(scripts_path, MAXPATHLEN, "%s/python", get_argv_exec_path());
scripts_dir = opendir(scripts_path);
if (!scripts_dir) {
@@ -3784,30 +3870,26 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
exit(-1);
}
- for_each_lang(scripts_path, scripts_dir, lang_dirent) {
- scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
- lang_dirent->d_name);
- lang_dir = opendir(lang_path);
- if (!lang_dir)
- continue;
+ while ((script_dirent = readdir(scripts_dir)) != NULL) {
+ if (script_dirent->d_type != DT_DIR &&
+ (script_dirent->d_type != DT_UNKNOWN ||
+ !is_directory(scripts_path, script_dirent))) {
- for_each_script(lang_path, lang_dir, script_dirent) {
- script_root = get_script_root(script_dirent, REPORT_SUFFIX);
+ script_root = get_script_root(script_dirent, ".py");
if (script_root) {
desc = script_desc__findnew(script_root);
scnprintf(script_path, MAXPATHLEN, "%s/%s",
- lang_path, script_dirent->d_name);
+ scripts_path, script_dirent->d_name);
read_script_info(desc, script_path);
free(script_root);
}
}
}
+ closedir(scripts_dir);
- fprintf(stdout, "List of available trace scripts:\n");
+ fprintf(stdout, "List of available scripts:\n");
list_for_each_entry(desc, &script_descs, node) {
- sprintf(first_half, "%s %s", desc->name,
- desc->args ? desc->args : "");
- fprintf(stdout, " %-36s %s\n", first_half,
+ fprintf(stdout, " %-36s %s\n", desc->name,
desc->half_liner ? desc->half_liner : "");
}
@@ -3843,94 +3925,6 @@ static void free_dlarg(void)
free(dlargv);
}
-static char *get_script_path(const char *script_root, const char *suffix)
-{
- struct dirent *script_dirent, *lang_dirent;
- char scripts_path[MAXPATHLEN];
- char script_path[MAXPATHLEN];
- DIR *scripts_dir, *lang_dir;
- char lang_path[MAXPATHLEN];
- char *__script_root;
-
- snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
-
- scripts_dir = opendir(scripts_path);
- if (!scripts_dir)
- return NULL;
-
- for_each_lang(scripts_path, scripts_dir, lang_dirent) {
- scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
- lang_dirent->d_name);
- lang_dir = opendir(lang_path);
- if (!lang_dir)
- continue;
-
- for_each_script(lang_path, lang_dir, script_dirent) {
- __script_root = get_script_root(script_dirent, suffix);
- if (__script_root && !strcmp(script_root, __script_root)) {
- free(__script_root);
- closedir(scripts_dir);
- scnprintf(script_path, MAXPATHLEN, "%s/%s",
- lang_path, script_dirent->d_name);
- closedir(lang_dir);
- return strdup(script_path);
- }
- free(__script_root);
- }
- closedir(lang_dir);
- }
- closedir(scripts_dir);
-
- return NULL;
-}
-
-static bool is_top_script(const char *script_path)
-{
- return ends_with(script_path, "top") != NULL;
-}
-
-static int has_required_arg(char *script_path)
-{
- struct script_desc *desc;
- int n_args = 0;
- char *p;
-
- desc = script_desc__new(NULL);
-
- if (read_script_info(desc, script_path))
- goto out;
-
- if (!desc->args)
- goto out;
-
- for (p = desc->args; *p; p++)
- if (*p == '<')
- n_args++;
-out:
- script_desc__delete(desc);
-
- return n_args;
-}
-
-static int have_cmd(int argc, const char **argv)
-{
- char **__argv = calloc(argc, sizeof(const char *));
-
- if (!__argv) {
- pr_err("malloc failed\n");
- return -1;
- }
-
- memcpy(__argv, argv, sizeof(const char *) * argc);
- argc = parse_options(argc, (const char **)__argv, record_options,
- NULL, PARSE_OPT_STOP_AT_NON_OPTION);
- free(__argv);
-
- system_wide = (argc == 0);
-
- return 0;
-}
-
static void script__setup_sample_type(struct perf_script *script)
{
struct perf_session *session = script->session;
@@ -4110,22 +4104,96 @@ static int parse_callret_trace(const struct option *opt __maybe_unused,
return 0;
}
+/*
+ * Detect scripts written for the removed legacy embedded Python scripting API.
+ *
+ * Without an embedded interpreter invoking trace_begin()/process_event()/trace_end(),
+ * executing a callback-only legacy script directly under `python3` would simply
+ * define top-level functions and silently exit with status 0 without processing
+ * any events.
+ *
+ * Note on ordering and heuristics:
+ * 1) "perf_trace_context" and "Perf-Trace-Util" must be checked BEFORE
+ * "import perf", because "import perf" is a substring prefix of
+ * "import perf_trace_context".
+ * 2) Defining `def process_event(`, `def trace_begin(`, or `def trace_end(`
+ * is only flagged as legacy when `!has_perf_import`, because standalone
+ * `import perf` scripts commonly define a helper named `def process_event(sample):`
+ * to pass as the `sample=` callback to `perf.session(...)`.
+ */
+static bool is_legacy_python_script(const char *path)
+{
+ struct stat st;
+ int fd;
+ FILE *fp;
+ char line[1024];
+ bool has_legacy_cb = false;
+ bool has_perf_import = false;
+
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ return false;
+
+ if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode)) {
+ close(fd);
+ return false;
+ }
+
+ fp = fdopen(fd, "r");
+ if (!fp) {
+ close(fd);
+ return false;
+ }
+
+ while (fgets(line, sizeof(line), fp)) {
+ const char *p = skip_spaces(line);
+
+ if (*p == '#')
+ continue;
+ if ((strstr(p, "import perf") && !strstr(p, "import perf_trace_context")) ||
+ strstr(p, "from perf ") ||
+ strstr(p, "__main__"))
+ has_perf_import = true;
+ if (strstr(p, "perf_trace_context") ||
+ strstr(p, "Perf-Trace-Util") ||
+ strstr(p, "def process_event(") ||
+ strstr(p, "def trace_begin(") ||
+ strstr(p, "def trace_end("))
+ has_legacy_cb = true;
+ }
+ fclose(fp);
+ return has_legacy_cb && !has_perf_import;
+}
+
+static volatile sig_atomic_t script_child_pid;
+
+static void forward_script_sig(int sig, siginfo_t *info, void *ucontext __maybe_unused)
+{
+ /*
+ * Terminal-generated signals (Ctrl-C / Ctrl-\) have si_code > 0
+ * (SI_KERNEL) and are already delivered by the TTY driver to the
+ * entire foreground process group, including the child script.
+ * Signals sent directly to the perf process via kill(2) / sigqueue(3)
+ * have si_code <= 0 (SI_USER, SI_QUEUE, etc.) and must be forwarded
+ * to the child script so it can catch KeyboardInterrupt / SIGTERM
+ * and flush its output before exiting.
+ */
+ if (script_child_pid > 0 && (sig == SIGTERM || !info || info->si_code <= 0))
+ kill(script_child_pid, sig);
+}
+
int cmd_script(int argc, const char **argv)
{
bool show_full_info = false;
bool header = false;
bool header_only = false;
- bool script_started = false;
bool unsorted_dump = false;
bool merge_deferred_callchains = true;
- char *rec_script_path = NULL;
- char *rep_script_path = NULL;
struct perf_session *session;
struct itrace_synth_opts itrace_synth_opts = {
.set = false,
.default_no_sample = true,
};
- char *script_path = NULL;
const char *dlfilter_file = NULL;
const char **__argv;
int i, j, err = 0;
@@ -4146,11 +4214,10 @@ int cmd_script(int argc, const char **argv)
list_available_scripts),
OPT_CALLBACK_NOOPT(0, "list-dlfilters", NULL, NULL, "list available dlfilters",
list_available_dlfilters),
- OPT_CALLBACK('s', "script", NULL, "name",
- "script file name (lang:script name, script name, or *)",
- parse_scriptname),
- OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
- "generate perf-script.xx script in specified language"),
+ { .type = OPTION_CALLBACK, .short_name = 's', .long_name = "script",
+ .value = NULL, .argh = "name",
+ .help = "script file name (lang:script name, script name, or *)",
+ .callback = parse_scriptname, .flags = PARSE_OPT_HIDDEN },
OPT_STRING(0, "dlfilter", &dlfilter_file, "file", "filter .so file name"),
OPT_CALLBACK(0, "dlarg", NULL, "argument", "filter argument",
add_dlarg),
@@ -4179,8 +4246,6 @@ int cmd_script(int argc, const char **argv)
"code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat,"
"brcntr",
parse_output_fields),
- OPT_BOOLEAN('a', "all-cpus", &system_wide,
- "system-wide collection from all CPUs"),
OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
"only consider symbols in these DSOs"),
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
@@ -4277,22 +4342,16 @@ int cmd_script(int argc, const char **argv)
OPTS_EVSWITCH(&script.evswitch),
OPT_END()
};
- const char * const script_subcommands[] = { "record", "report", NULL };
const char *script_usage[] = {
"perf script [<options>]",
- "perf script [<options>] record <script> [<record-options>] <command>",
- "perf script [<options>] report <script> [script-args]",
- "perf script [<options>] <script> [<record-options>] <command>",
- "perf script [<options>] <top-script> [script-args]",
+ "perf script [<options>] <script> [script-args]",
NULL
};
struct perf_env *env;
perf_set_singlethreaded();
- setup_scripting();
-
- argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
+ argc = parse_options_subcommand(argc, argv, options, NULL, script_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (symbol_conf.guestmount ||
@@ -4315,22 +4374,6 @@ int cmd_script(int argc, const char **argv)
if (symbol__validate_sym_arguments())
return -1;
- if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
- rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
- if (!rec_script_path)
- return cmd_record(argc, argv);
- }
-
- if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
- rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
- if (!rep_script_path) {
- fprintf(stderr,
- "Please specify a valid report script"
- "(see 'perf script -l' for listing)\n");
- return -1;
- }
- }
-
if (reltime && deltatime) {
fprintf(stderr,
"reltime and deltatime - the two don't get along well. "
@@ -4345,149 +4388,179 @@ int cmd_script(int argc, const char **argv)
/* make sure PERF_EXEC_PATH is set for scripts */
set_argv_exec_path(get_argv_exec_path());
- if (argc && !script_name && !rec_script_path && !rep_script_path) {
- int live_pipe[2];
- int rep_args;
- pid_t pid;
-
- rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
- rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
-
- if (!rec_script_path && !rep_script_path) {
- script_name = find_script(argv[0]);
- if (script_name) {
+ if (argc && !script_name) {
+ if (!strcmp(argv[0], "record") || !strcmp(argv[0], "report")) {
+ fprintf(stderr,
+ "The '%s' subcommand is no longer supported.\n",
+ argv[0]);
+ fprintf(stderr,
+ "Run 'perf script <script> [args]' directly.\n");
+ err = -1;
+ goto out;
+ }
+ script_name = find_script(argv[0]);
+ if (script_name) {
+ argc -= 1;
+ argv += 1;
+ if (argc && !strcmp(argv[0], "--")) {
argc -= 1;
argv += 1;
- goto script_found;
}
- usage_with_options_msg(script_usage, options,
- "Couldn't find script `%s'\n\n See perf"
- " script -l for available scripts.\n", argv[0]);
+ goto script_found;
}
+ usage_with_options_msg(script_usage, options,
+ "Couldn't find script `%s'\n\n"
+ " See perf script -l for available scripts.\n", argv[0]);
+ }
+script_found:
- if (is_top_script(argv[0])) {
- rep_args = argc - 1;
- } else {
- int rec_args;
-
- rep_args = has_required_arg(rep_script_path);
- rec_args = (argc - 1) - rep_args;
- if (rec_args < 0) {
- usage_with_options_msg(script_usage, options,
- "`%s' script requires options."
- "\n\n See perf script -l for available "
- "scripts and options.\n", argv[0]);
- }
- }
+ if (script_name) {
+ pid_t pid;
+ bool is_python = str_ends_with(script_name, ".py");
+ struct sigaction forward_sa = {
+ .sa_sigaction = forward_script_sig,
+ .sa_flags = SA_SIGINFO,
+ };
+ struct sigaction old_int, old_quit, old_term;
+ sigset_t block_mask, old_mask;
- if (pipe(live_pipe) < 0) {
- perror("failed to create pipe");
- return -1;
+ if (is_python && is_legacy_python_script(script_name)) {
+ pr_err("Error: '%s' uses the removed legacy embedded Python scripting API.\n"
+ "Please port it to a standalone script using 'import perf' (see 'man perf-script-python').\n",
+ script_name);
+ err = -EINVAL;
+ goto out;
}
+ if (cpu_list || symbol_conf.comm_list_str ||
+ symbol_conf.pid_list_str || symbol_conf.tid_list_str ||
+ script.time_str || dlfilter_file || dlargc > 0) {
+ pr_warning("Warning: Filtering options (-C, -c, --pid, --tid, --time, --dlfilter, --dlarg) are ignored for standalone scripts.\n");
+ }
+ /*
+ * Install forward_script_sig for SIGINT, SIGQUIT, and SIGTERM
+ * in the parent `perf` process while waiting for the child
+ * script, and restore the original handlers and signal mask in
+ * the child before execvp(). When the user presses Ctrl-C
+ * during a live trace, the terminal delivers SIGINT (SI_KERNEL)
+ * to the entire foreground process group; ignoring SI_KERNEL in
+ * the parent prevents `perf` from terminating immediately and
+ * allows the child Python script to catch KeyboardInterrupt,
+ * print its summary/report, and finish cleanup before exiting.
+ * When a signal is sent directly to `perf` via kill(2) (e.g.
+ * from a backgrounded job in a non-interactive shell), si_code
+ * is <= 0 (SI_USER) and forward_script_sig forwards it to the
+ * child script.
+ */
+ sigemptyset(&forward_sa.sa_mask);
+ sigemptyset(&block_mask);
+ sigaddset(&block_mask, SIGINT);
+ sigaddset(&block_mask, SIGQUIT);
+ sigaddset(&block_mask, SIGTERM);
+ sigprocmask(SIG_BLOCK, &block_mask, &old_mask);
+ sigaction(SIGINT, &forward_sa, &old_int);
+ sigaction(SIGQUIT, &forward_sa, &old_quit);
+ sigaction(SIGTERM, &forward_sa, &old_term);
pid = fork();
if (pid < 0) {
- perror("failed to fork");
- return -1;
+ err = -errno;
+ sigaction(SIGINT, &old_int, NULL);
+ sigaction(SIGQUIT, &old_quit, NULL);
+ sigaction(SIGTERM, &old_term, NULL);
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
+ pr_err("failed to fork\n");
+ goto out;
}
-
- if (!pid) {
+ if (pid == 0) { /* child */
+ sigaction(SIGINT, &old_int, NULL);
+ sigaction(SIGQUIT, &old_quit, NULL);
+ sigaction(SIGTERM, &old_term, NULL);
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
+ __argv = calloc(argc + 6, sizeof(const char *));
j = 0;
+ if (!__argv)
+ _exit(127);
- dup2(live_pipe[1], 1);
- close(live_pipe[0]);
+ if (is_python) {
+ const char *python = getenv("PYTHON");
- if (is_top_script(argv[0])) {
- system_wide = true;
- } else if (!system_wide) {
- if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) {
- err = -1;
- goto out;
- }
+ if (!python || !*python)
+ python = "python3";
+ __argv[j++] = python;
+ __argv[j++] = "--";
+ __argv[j++] = script_name;
+ } else {
+ __argv[j++] = script_name;
}
-
- __argv = calloc(argc + 6, sizeof(const char *));
- if (!__argv) {
- pr_err("malloc failed\n");
- err = -ENOMEM;
- goto out;
+ if (input_name) {
+ __argv[j++] = "-i";
+ __argv[j++] = input_name;
+ } else {
+ struct stat st;
+ bool has_input_arg = false;
+
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argv[i], "-i") ||
+ strstarts(argv[i], "--input")) {
+ has_input_arg = true;
+ break;
+ }
+ }
+ if (!has_input_arg &&
+ fstat(STDIN_FILENO, &st) == 0 &&
+ S_ISFIFO(st.st_mode)) {
+ __argv[j++] = "-i";
+ __argv[j++] = "-";
+ }
}
-
- __argv[j++] = "/bin/sh";
- __argv[j++] = rec_script_path;
- if (system_wide)
- __argv[j++] = "-a";
- __argv[j++] = "-q";
- __argv[j++] = "-o";
- __argv[j++] = "-";
- for (i = rep_args + 1; i < argc; i++)
+ for (i = 0; i < argc; i++)
__argv[j++] = argv[i];
__argv[j++] = NULL;
- execvp("/bin/sh", (char **)__argv);
- free(__argv);
- exit(-1);
- }
+ if (symbol_conf.vmlinux_name)
+ setenv("PERF_SYMBOL_VMLINUX", symbol_conf.vmlinux_name, 1);
+ if (symbol_conf.kallsyms_name)
+ setenv("PERF_SYMBOL_KALLSYMS", symbol_conf.kallsyms_name, 1);
+ if (symbol_conf.symfs && symbol_conf.symfs[0])
+ setenv("PERF_SYMBOL_SYMFS", symbol_conf.symfs, 1);
- dup2(live_pipe[0], 0);
- close(live_pipe[1]);
+ execvp(__argv[0], (char **)__argv);
+ {
+ int err_code = errno;
- __argv = calloc(argc + 4, sizeof(const char *));
- if (!__argv) {
- pr_err("malloc failed\n");
- err = -ENOMEM;
- goto out;
- }
-
- j = 0;
- __argv[j++] = "/bin/sh";
- __argv[j++] = rep_script_path;
- for (i = 1; i < rep_args + 1; i++)
- __argv[j++] = argv[i];
- __argv[j++] = "-i";
- __argv[j++] = "-";
- __argv[j++] = NULL;
-
- execvp("/bin/sh", (char **)__argv);
- free(__argv);
- exit(-1);
- }
-script_found:
- if (rec_script_path)
- script_path = rec_script_path;
- if (rep_script_path)
- script_path = rep_script_path;
-
- if (script_path) {
- j = 0;
-
- if (!rec_script_path)
- system_wide = false;
- else if (!system_wide) {
- if (have_cmd(argc - 1, &argv[1]) != 0) {
- err = -1;
+ pr_err("failed to execute script '%s': %s\n",
+ script_name, strerror(err_code));
+ _exit(err_code);
+ }
+ } else { /* parent */
+ int status = 0;
+
+ script_child_pid = pid;
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
+ while (waitpid(pid, &status, 0) != pid) {
+ if (errno == EINTR)
+ continue;
+ pr_err("failed to wait for script '%s': %s\n",
+ script_name, strerror(errno));
+ err = -errno;
+ script_child_pid = 0;
+ sigaction(SIGINT, &old_int, NULL);
+ sigaction(SIGQUIT, &old_quit, NULL);
+ sigaction(SIGTERM, &old_term, NULL);
goto out;
}
- }
-
- __argv = calloc(argc + 2, sizeof(const char *));
- if (!__argv) {
- pr_err("malloc failed\n");
- err = -ENOMEM;
+ script_child_pid = 0;
+ sigaction(SIGINT, &old_int, NULL);
+ sigaction(SIGQUIT, &old_quit, NULL);
+ sigaction(SIGTERM, &old_term, NULL);
+ if (WIFEXITED(status))
+ err = WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ err = 128 + WTERMSIG(status);
+ else
+ err = -1;
goto out;
}
-
- __argv[j++] = "/bin/sh";
- __argv[j++] = script_path;
- if (system_wide)
- __argv[j++] = "-a";
- for (i = 2; i < argc; i++)
- __argv[j++] = argv[i];
- __argv[j++] = NULL;
-
- execvp("/bin/sh", (char **)__argv);
- free(__argv);
- exit(-1);
}
if (dlfilter_file) {
@@ -4579,79 +4652,11 @@ int cmd_script(int argc, const char **argv)
goto out_delete;
}
#endif
- if (generate_script_lang) {
- struct stat perf_stat;
- int input;
- char *filename = strdup("perf-script");
-
- if (output_set_by_user()) {
- fprintf(stderr,
- "custom fields not supported for generated scripts");
- err = -EINVAL;
- goto out_delete;
- }
-
- input = open(data.path, O_RDONLY); /* input_name */
- if (input < 0) {
- err = -errno;
- perror("failed to open file");
- goto out_delete;
- }
-
- err = fstat(input, &perf_stat);
- if (err < 0) {
- perror("failed to stat file");
- goto out_delete;
- }
-
- if (!perf_stat.st_size) {
- fprintf(stderr, "zero-sized file, nothing to do!\n");
- goto out_delete;
- }
-
- scripting_ops = script_spec__lookup(generate_script_lang);
- if (!scripting_ops && ends_with(generate_script_lang, ".py")) {
- scripting_ops = script_spec__lookup("python");
- free(filename);
- filename = strdup(generate_script_lang);
- filename[strlen(filename) - 3] = '\0';
- } else if (!scripting_ops && ends_with(generate_script_lang, ".pl")) {
- scripting_ops = script_spec__lookup("perl");
- free(filename);
- filename = strdup(generate_script_lang);
- filename[strlen(filename) - 3] = '\0';
- }
- if (!scripting_ops) {
- fprintf(stderr, "invalid language specifier '%s'\n", generate_script_lang);
- err = -ENOENT;
- goto out_delete;
- }
- if (!filename) {
- err = -ENOMEM;
- goto out_delete;
- }
-#ifdef HAVE_LIBTRACEEVENT
- err = scripting_ops->generate_script(session->tevent.pevent, filename);
-#else
- err = scripting_ops->generate_script(NULL, filename);
-#endif
- free(filename);
- goto out_delete;
- }
err = dlfilter__start(dlfilter, session);
if (err)
goto out_delete;
- if (script_name) {
- err = scripting_ops->start_script(script_name, argc, argv, session);
- if (err)
- goto out_delete;
- pr_debug("perf script started with script %s\n\n", script_name);
- script_started = true;
- }
-
-
err = perf_session__check_output_opt(session);
if (err < 0)
goto out_delete;
@@ -4679,8 +4684,6 @@ int cmd_script(int argc, const char **argv)
err = __cmd_script(&script);
- flush_scripting();
-
if (verbose > 2 || debug_kmaps)
perf_session__dump_kmaps(session);
@@ -4695,10 +4698,9 @@ int cmd_script(int argc, const char **argv)
perf_session__delete(session);
perf_script__exit(&script);
- if (script_started)
- cleanup_scripting();
+out:
+ zfree(&script_name);
dlfilter__cleanup(dlfilter);
free_dlarg();
-out:
return err;
}
diff --git a/tools/perf/scripts/Build b/tools/perf/scripts/Build
deleted file mode 100644
index fbeab8fff88b..000000000000
--- a/tools/perf/scripts/Build
+++ /dev/null
@@ -1,3 +0,0 @@
-ifeq ($(CONFIG_LIBTRACEEVENT),y)
- perf-util-$(CONFIG_LIBPERL) += perl/Perf-Trace-Util/
-endif
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Build b/tools/perf/scripts/perl/Perf-Trace-Util/Build
deleted file mode 100644
index 01a1a0ed51ae..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Build
+++ /dev/null
@@ -1,9 +0,0 @@
-perf-util-y += Context.o
-
-CFLAGS_Context.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-bad-function-cast -Wno-declaration-after-statement -Wno-switch-enum
-CFLAGS_Context.o += -Wno-unused-parameter -Wno-nested-externs -Wno-undef
-CFLAGS_Context.o += -Wno-switch-default -Wno-shadow -Wno-thread-safety-analysis
-
-ifeq ($(CC_NO_CLANG), 1)
- CFLAGS_Context.o += -Wno-unused-command-line-argument
-endif
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
deleted file mode 100644
index 25c47d23a130..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * This file was generated automatically by ExtUtils::ParseXS version 2.18_02 from the
- * contents of Context.xs. Do not edit this file, edit Context.xs instead.
- *
- * ANY CHANGES MADE HERE WILL BE LOST!
- */
-#include <stdbool.h>
-#ifndef HAS_BOOL
-# define HAS_BOOL 1
-#endif
-#line 1 "Context.xs"
-/*
- * Context.xs. XS interfaces for perf script.
- *
- * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
- */
-
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-#include "../../../util/trace-event.h"
-
-#ifndef PERL_UNUSED_VAR
-# define PERL_UNUSED_VAR(var) if (0) var = var
-#endif
-
-#line 42 "Context.c"
-
-XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */
-XS(XS_Perf__Trace__Context_common_pc)
-{
-#ifdef dVAR
- dVAR; dXSARGS;
-#else
- dXSARGS;
-#endif
- if (items != 1)
- Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_pc", "context");
- PERL_UNUSED_VAR(cv); /* -W */
- {
- struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
- int RETVAL;
- dXSTARG;
-
- RETVAL = common_pc(context);
- XSprePUSH; PUSHi((IV)RETVAL);
- }
- XSRETURN(1);
-}
-
-
-XS(XS_Perf__Trace__Context_common_flags); /* prototype to pass -Wmissing-prototypes */
-XS(XS_Perf__Trace__Context_common_flags)
-{
-#ifdef dVAR
- dVAR; dXSARGS;
-#else
- dXSARGS;
-#endif
- if (items != 1)
- Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_flags", "context");
- PERL_UNUSED_VAR(cv); /* -W */
- {
- struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
- int RETVAL;
- dXSTARG;
-
- RETVAL = common_flags(context);
- XSprePUSH; PUSHi((IV)RETVAL);
- }
- XSRETURN(1);
-}
-
-
-XS(XS_Perf__Trace__Context_common_lock_depth); /* prototype to pass -Wmissing-prototypes */
-XS(XS_Perf__Trace__Context_common_lock_depth)
-{
-#ifdef dVAR
- dVAR; dXSARGS;
-#else
- dXSARGS;
-#endif
- if (items != 1)
- Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_lock_depth", "context");
- PERL_UNUSED_VAR(cv); /* -W */
- {
- struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
- int RETVAL;
- dXSTARG;
-
- RETVAL = common_lock_depth(context);
- XSprePUSH; PUSHi((IV)RETVAL);
- }
- XSRETURN(1);
-}
-
-#ifdef __cplusplus
-extern "C"
-#endif
-XS(boot_Perf__Trace__Context); /* prototype to pass -Wmissing-prototypes */
-XS(boot_Perf__Trace__Context)
-{
-#ifdef dVAR
- dVAR; dXSARGS;
-#else
- dXSARGS;
-#endif
- const char* file = __FILE__;
-
- PERL_UNUSED_VAR(cv); /* -W */
- PERL_UNUSED_VAR(items); /* -W */
- XS_VERSION_BOOTCHECK ;
-
- newXSproto("Perf::Trace::Context::common_pc", XS_Perf__Trace__Context_common_pc, file, "$");
- newXSproto("Perf::Trace::Context::common_flags", XS_Perf__Trace__Context_common_flags, file, "$");
- newXSproto("Perf::Trace::Context::common_lock_depth", XS_Perf__Trace__Context_common_lock_depth, file, "$");
- if (PL_unitcheckav)
- call_list(PL_scopestack_ix, PL_unitcheckav);
- XSRETURN_YES;
-}
-
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
deleted file mode 100644
index 8c7ea42444d1..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Context.xs. XS interfaces for perf script.
- *
- * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-#include "../../../perf.h"
-#include "../../../util/trace-event.h"
-
-MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
-PROTOTYPES: ENABLE
-
-int
-common_pc(context)
- struct scripting_context * context
-
-int
-common_flags(context)
- struct scripting_context * context
-
-int
-common_lock_depth(context)
- struct scripting_context * context
-
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
deleted file mode 100644
index e8994332d7dc..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL
+++ /dev/null
@@ -1,18 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-use 5.010000;
-use ExtUtils::MakeMaker;
-# See lib/ExtUtils/MakeMaker.pm for details of how to influence
-# the contents of the Makefile that is written.
-WriteMakefile(
- NAME => 'Perf::Trace::Context',
- VERSION_FROM => 'lib/Perf/Trace/Context.pm', # finds $VERSION
- PREREQ_PM => {}, # e.g., Module::Name => 1.1
- ($] >= 5.005 ? ## Add these new keywords supported since 5.005
- (ABSTRACT_FROM => 'lib/Perf/Trace/Context.pm', # retrieve abstract from module
- AUTHOR => 'Tom Zanussi <tzanussi@gmail.com>') : ()),
- LIBS => [''], # e.g., '-lm'
- DEFINE => '-I ../..', # e.g., '-DHAVE_SOMETHING'
- INC => '-I.', # e.g., '-I. -I/usr/include/other'
- # Un-comment this if you add C files to link with later:
- OBJECT => 'Context.o', # link all the C files too
-);
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/README b/tools/perf/scripts/perl/Perf-Trace-Util/README
deleted file mode 100644
index 2f0c7f3043ee..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/README
+++ /dev/null
@@ -1,59 +0,0 @@
-Perf-Trace-Util version 0.01
-============================
-
-This module contains utility functions for use with perf script.
-
-Core.pm and Util.pm are pure Perl modules; Core.pm contains routines
-that the core perf support for Perl calls on and should always be
-'used', while Util.pm contains useful but optional utility functions
-that scripts may want to use. Context.pm contains the Perl->C
-interface that allows scripts to access data in the embedding perf
-executable; scripts wishing to do that should 'use Context.pm'.
-
-The Perl->C perf interface is completely driven by Context.xs. If you
-want to add new Perl functions that end up accessing C data in the
-perf executable, you add desciptions of the new functions here.
-scripting_context is a pointer to the perf data in the perf executable
-that you want to access - it's passed as the second parameter,
-$context, to all handler functions.
-
-After you do that:
-
- perl Makefile.PL # to create a Makefile for the next step
- make # to create Context.c
-
- edit Context.c to add const to the char* file = __FILE__ line in
- XS(boot_Perf__Trace__Context) to silence a warning/error.
-
- You can delete the Makefile, object files and anything else that was
- generated e.g. blib and shared library, etc, except for of course
- Context.c
-
- You should then be able to run the normal perf make as usual.
-
-INSTALLATION
-
-Building perf with perf script Perl scripting should install this
-module in the right place.
-
-You should make sure libperl and ExtUtils/Embed.pm are installed first
-e.g. apt-get install libperl-dev or yum install perl-ExtUtils-Embed.
-
-DEPENDENCIES
-
-This module requires these other modules and libraries:
-
- None
-
-COPYRIGHT AND LICENCE
-
-Copyright (C) 2009 by Tom Zanussi <tzanussi@gmail.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself, either Perl version 5.10.0 or,
-at your option, any later version of Perl 5 you may have available.
-
-Alternatively, this software may be distributed under the terms of the
-GNU General Public License ("GPL") version 2 as published by the Free
-Software Foundation.
-
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
deleted file mode 100644
index 4e2f6039ac92..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Context.pm
+++ /dev/null
@@ -1,55 +0,0 @@
-package Perf::Trace::Context;
-
-use 5.010000;
-use strict;
-use warnings;
-
-require Exporter;
-
-our @ISA = qw(Exporter);
-
-our %EXPORT_TAGS = ( 'all' => [ qw(
-) ] );
-
-our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
-
-our @EXPORT = qw(
- common_pc common_flags common_lock_depth
-);
-
-our $VERSION = '0.01';
-
-require XSLoader;
-XSLoader::load('Perf::Trace::Context', $VERSION);
-
-1;
-__END__
-=head1 NAME
-
-Perf::Trace::Context - Perl extension for accessing functions in perf.
-
-=head1 SYNOPSIS
-
- use Perf::Trace::Context;
-
-=head1 SEE ALSO
-
-Perf (script) documentation
-
-=head1 AUTHOR
-
-Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2009 by Tom Zanussi
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself, either Perl version 5.10.0 or,
-at your option, any later version of Perl 5 you may have available.
-
-Alternatively, this software may be distributed under the terms of the
-GNU General Public License ("GPL") version 2 as published by the Free
-Software Foundation.
-
-=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
deleted file mode 100644
index 9158458d3eeb..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Core.pm
+++ /dev/null
@@ -1,192 +0,0 @@
-package Perf::Trace::Core;
-
-use 5.010000;
-use strict;
-use warnings;
-
-require Exporter;
-
-our @ISA = qw(Exporter);
-
-our %EXPORT_TAGS = ( 'all' => [ qw(
-) ] );
-
-our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
-
-our @EXPORT = qw(
-define_flag_field define_flag_value flag_str dump_flag_fields
-define_symbolic_field define_symbolic_value symbol_str dump_symbolic_fields
-trace_flag_str
-);
-
-our $VERSION = '0.01';
-
-my %trace_flags = (0x00 => "NONE",
- 0x01 => "IRQS_OFF",
- 0x02 => "IRQS_NOSUPPORT",
- 0x04 => "NEED_RESCHED",
- 0x08 => "HARDIRQ",
- 0x10 => "SOFTIRQ");
-
-sub trace_flag_str
-{
- my ($value) = @_;
-
- my $string;
-
- my $print_delim = 0;
-
- foreach my $idx (sort {$a <=> $b} keys %trace_flags) {
- if (!$value && !$idx) {
- $string .= "NONE";
- last;
- }
-
- if ($idx && ($value & $idx) == $idx) {
- if ($print_delim) {
- $string .= " | ";
- }
- $string .= "$trace_flags{$idx}";
- $print_delim = 1;
- $value &= ~$idx;
- }
- }
-
- return $string;
-}
-
-my %flag_fields;
-my %symbolic_fields;
-
-sub flag_str
-{
- my ($event_name, $field_name, $value) = @_;
-
- my $string;
-
- if ($flag_fields{$event_name}{$field_name}) {
- my $print_delim = 0;
- foreach my $idx (sort {$a <=> $b} keys %{$flag_fields{$event_name}{$field_name}{"values"}}) {
- if (!$value && !$idx) {
- $string .= "$flag_fields{$event_name}{$field_name}{'values'}{$idx}";
- last;
- }
- if ($idx && ($value & $idx) == $idx) {
- if ($print_delim && $flag_fields{$event_name}{$field_name}{'delim'}) {
- $string .= " $flag_fields{$event_name}{$field_name}{'delim'} ";
- }
- $string .= "$flag_fields{$event_name}{$field_name}{'values'}{$idx}";
- $print_delim = 1;
- $value &= ~$idx;
- }
- }
- }
-
- return $string;
-}
-
-sub define_flag_field
-{
- my ($event_name, $field_name, $delim) = @_;
-
- $flag_fields{$event_name}{$field_name}{"delim"} = $delim;
-}
-
-sub define_flag_value
-{
- my ($event_name, $field_name, $value, $field_str) = @_;
-
- $flag_fields{$event_name}{$field_name}{"values"}{$value} = $field_str;
-}
-
-sub dump_flag_fields
-{
- for my $event (keys %flag_fields) {
- print "event $event:\n";
- for my $field (keys %{$flag_fields{$event}}) {
- print " field: $field:\n";
- print " delim: $flag_fields{$event}{$field}{'delim'}\n";
- foreach my $idx (sort {$a <=> $b} keys %{$flag_fields{$event}{$field}{"values"}}) {
- print " value $idx: $flag_fields{$event}{$field}{'values'}{$idx}\n";
- }
- }
- }
-}
-
-sub symbol_str
-{
- my ($event_name, $field_name, $value) = @_;
-
- if ($symbolic_fields{$event_name}{$field_name}) {
- foreach my $idx (sort {$a <=> $b} keys %{$symbolic_fields{$event_name}{$field_name}{"values"}}) {
- if (!$value && !$idx) {
- return "$symbolic_fields{$event_name}{$field_name}{'values'}{$idx}";
- last;
- }
- if ($value == $idx) {
- return "$symbolic_fields{$event_name}{$field_name}{'values'}{$idx}";
- }
- }
- }
-
- return undef;
-}
-
-sub define_symbolic_field
-{
- my ($event_name, $field_name) = @_;
-
- # nothing to do, really
-}
-
-sub define_symbolic_value
-{
- my ($event_name, $field_name, $value, $field_str) = @_;
-
- $symbolic_fields{$event_name}{$field_name}{"values"}{$value} = $field_str;
-}
-
-sub dump_symbolic_fields
-{
- for my $event (keys %symbolic_fields) {
- print "event $event:\n";
- for my $field (keys %{$symbolic_fields{$event}}) {
- print " field: $field:\n";
- foreach my $idx (sort {$a <=> $b} keys %{$symbolic_fields{$event}{$field}{"values"}}) {
- print " value $idx: $symbolic_fields{$event}{$field}{'values'}{$idx}\n";
- }
- }
- }
-}
-
-1;
-__END__
-=head1 NAME
-
-Perf::Trace::Core - Perl extension for perf script
-
-=head1 SYNOPSIS
-
- use Perf::Trace::Core
-
-=head1 SEE ALSO
-
-Perf (script) documentation
-
-=head1 AUTHOR
-
-Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2009 by Tom Zanussi
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself, either Perl version 5.10.0 or,
-at your option, any later version of Perl 5 you may have available.
-
-Alternatively, this software may be distributed under the terms of the
-GNU General Public License ("GPL") version 2 as published by the Free
-Software Foundation.
-
-=cut
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
deleted file mode 100644
index 053500114625..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
+++ /dev/null
@@ -1,94 +0,0 @@
-package Perf::Trace::Util;
-
-use 5.010000;
-use strict;
-use warnings;
-
-require Exporter;
-
-our @ISA = qw(Exporter);
-
-our %EXPORT_TAGS = ( 'all' => [ qw(
-) ] );
-
-our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
-
-our @EXPORT = qw(
-avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
-clear_term
-);
-
-our $VERSION = '0.01';
-
-sub avg
-{
- my ($total, $n) = @_;
-
- return $total / $n;
-}
-
-my $NSECS_PER_SEC = 1000000000;
-
-sub nsecs
-{
- my ($secs, $nsecs) = @_;
-
- return $secs * $NSECS_PER_SEC + $nsecs;
-}
-
-sub nsecs_secs {
- my ($nsecs) = @_;
-
- return $nsecs / $NSECS_PER_SEC;
-}
-
-sub nsecs_nsecs {
- my ($nsecs) = @_;
-
- return $nsecs % $NSECS_PER_SEC;
-}
-
-sub nsecs_str {
- my ($nsecs) = @_;
-
- my $str = sprintf("%5u.%09u", nsecs_secs($nsecs), nsecs_nsecs($nsecs));
-
- return $str;
-}
-
-sub clear_term
-{
- print "\x1b[H\x1b[2J";
-}
-
-1;
-__END__
-=head1 NAME
-
-Perf::Trace::Util - Perl extension for perf script
-
-=head1 SYNOPSIS
-
- use Perf::Trace::Util;
-
-=head1 SEE ALSO
-
-Perf (script) documentation
-
-=head1 AUTHOR
-
-Tom Zanussi, E<lt>tzanussi@gmail.com<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2009 by Tom Zanussi
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself, either Perl version 5.10.0 or,
-at your option, any later version of Perl 5 you may have available.
-
-Alternatively, this software may be distributed under the terms of the
-GNU General Public License ("GPL") version 2 as published by the Free
-Software Foundation.
-
-=cut
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/typemap b/tools/perf/scripts/perl/Perf-Trace-Util/typemap
deleted file mode 100644
index 840836804aa7..000000000000
--- a/tools/perf/scripts/perl/Perf-Trace-Util/typemap
+++ /dev/null
@@ -1 +0,0 @@
-struct scripting_context * T_PTR
diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-record b/tools/perf/scripts/perl/bin/check-perf-trace-record
deleted file mode 100644
index 423ad6aed056..000000000000
--- a/tools/perf/scripts/perl/bin/check-perf-trace-record
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-perf record -a -e kmem:kmalloc -e irq:softirq_entry -e kmem:kfree
diff --git a/tools/perf/scripts/perl/bin/failed-syscalls-record b/tools/perf/scripts/perl/bin/failed-syscalls-record
deleted file mode 100644
index 74685f318379..000000000000
--- a/tools/perf/scripts/perl/bin/failed-syscalls-record
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-(perf record -e raw_syscalls:sys_exit $@ || \
- perf record -e syscalls:sys_exit $@) 2> /dev/null
diff --git a/tools/perf/scripts/perl/bin/failed-syscalls-report b/tools/perf/scripts/perl/bin/failed-syscalls-report
deleted file mode 100644
index 9f83cc1ad8ba..000000000000
--- a/tools/perf/scripts/perl/bin/failed-syscalls-report
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-# description: system-wide failed syscalls
-# args: [comm]
-if [ $# -gt 0 ] ; then
- if ! expr match "$1" "-" > /dev/null ; then
- comm=$1
- shift
- fi
-fi
-perf script $@ -s "$PERF_EXEC_PATH"/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
deleted file mode 100644
index 33efc8673aae..000000000000
--- a/tools/perf/scripts/perl/bin/rw-by-file-record
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-perf record -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@
-
diff --git a/tools/perf/scripts/perl/bin/rw-by-file-report b/tools/perf/scripts/perl/bin/rw-by-file-report
deleted file mode 100644
index 77200b3f3100..000000000000
--- a/tools/perf/scripts/perl/bin/rw-by-file-report
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-# description: r/w activity for a program, by file
-# args: <comm>
-if [ $# -lt 1 ] ; then
- echo "usage: rw-by-file <comm>"
- exit
-fi
-comm=$1
-shift
-perf script $@ -s "$PERF_EXEC_PATH"/scripts/perl/rw-by-file.pl $comm
diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-record b/tools/perf/scripts/perl/bin/rw-by-pid-record
deleted file mode 100644
index 7cb9db230448..000000000000
--- a/tools/perf/scripts/perl/bin/rw-by-pid-record
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-perf record -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
deleted file mode 100644
index a27b9f311f95..000000000000
--- a/tools/perf/scripts/perl/bin/rw-by-pid-report
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-# description: system-wide r/w activity
-perf script $@ -s "$PERF_EXEC_PATH"/scripts/perl/rw-by-pid.pl
diff --git a/tools/perf/scripts/perl/bin/rwtop-record b/tools/perf/scripts/perl/bin/rwtop-record
deleted file mode 100644
index 7cb9db230448..000000000000
--- a/tools/perf/scripts/perl/bin/rwtop-record
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-perf record -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
deleted file mode 100644
index 83e11ec2e190..000000000000
--- a/tools/perf/scripts/perl/bin/rwtop-report
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-# description: system-wide r/w top
-# args: [interval]
-n_args=0
-for i in "$@"
-do
- if expr match "$i" "-" > /dev/null ; then
- break
- fi
- n_args=$(( $n_args + 1 ))
-done
-if [ "$n_args" -gt 1 ] ; then
- echo "usage: rwtop-report [interval]"
- exit
-fi
-if [ "$n_args" -gt 0 ] ; then
- interval=$1
- shift
-fi
-perf script $@ -s "$PERF_EXEC_PATH"/scripts/perl/rwtop.pl $interval
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-record b/tools/perf/scripts/perl/bin/wakeup-latency-record
deleted file mode 100644
index 464251a1bd7e..000000000000
--- a/tools/perf/scripts/perl/bin/wakeup-latency-record
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-perf record -e sched:sched_switch -e sched:sched_wakeup $@
-
-
-
-
diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-report b/tools/perf/scripts/perl/bin/wakeup-latency-report
deleted file mode 100644
index 889e8130cca5..000000000000
--- a/tools/perf/scripts/perl/bin/wakeup-latency-report
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-# description: system-wide min/max/avg wakeup latency
-perf script $@ -s "$PERF_EXEC_PATH"/scripts/perl/wakeup-latency.pl
diff --git a/tools/perf/scripts/perl/check-perf-trace.pl b/tools/perf/scripts/perl/check-perf-trace.pl
deleted file mode 100644
index d307ce8fd6ed..000000000000
--- a/tools/perf/scripts/perl/check-perf-trace.pl
+++ /dev/null
@@ -1,106 +0,0 @@
-# perf script event handlers, generated by perf script -g perl
-# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
-# Licensed under the terms of the GNU GPL License version 2
-
-# This script tests basic functionality such as flag and symbol
-# strings, common_xxx() calls back into perf, begin, end, unhandled
-# events, etc. Basically, if this script runs successfully and
-# displays expected results, perl scripting support should be ok.
-
-use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
-use lib "./Perf-Trace-Util/lib";
-use Perf::Trace::Core;
-use Perf::Trace::Context;
-use Perf::Trace::Util;
-
-sub trace_begin
-{
- print "trace_begin\n";
-}
-
-sub trace_end
-{
- print "trace_end\n";
-
- print_unhandled();
-}
-
-sub irq::softirq_entry
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $vec) = @_;
-
- print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm);
-
- print_uncommon($context);
-
- printf("vec=%s\n",
- symbol_str("irq::softirq_entry", "vec", $vec));
-}
-
-sub kmem::kmalloc
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $call_site, $ptr, $bytes_req, $bytes_alloc,
- $gfp_flags) = @_;
-
- print_header($event_name, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm);
-
- print_uncommon($context);
-
- printf("call_site=%p, ptr=%p, bytes_req=%u, bytes_alloc=%u, ".
- "gfp_flags=%s\n",
- $call_site, $ptr, $bytes_req, $bytes_alloc,
-
- flag_str("kmem::kmalloc", "gfp_flags", $gfp_flags));
-}
-
-# print trace fields not included in handler args
-sub print_uncommon
-{
- my ($context) = @_;
-
- printf("common_preempt_count=%d, common_flags=%s, common_lock_depth=%d, ",
- common_pc($context), trace_flag_str(common_flags($context)),
- common_lock_depth($context));
-
-}
-
-my %unhandled;
-
-sub print_unhandled
-{
- if ((scalar keys %unhandled) == 0) {
- return;
- }
-
- print "\nunhandled events:\n\n";
-
- printf("%-40s %10s\n", "event", "count");
- printf("%-40s %10s\n", "----------------------------------------",
- "-----------");
-
- foreach my $event_name (keys %unhandled) {
- printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
- }
-}
-
-sub trace_unhandled
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain) = @_;
-
- $unhandled{$event_name}++;
-}
-
-sub print_header
-{
- my ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;
-
- printf("%-20s %5u %05u.%09u %8u %-20s ",
- $event_name, $cpu, $secs, $nsecs, $pid, $comm);
-}
diff --git a/tools/perf/scripts/perl/failed-syscalls.pl b/tools/perf/scripts/perl/failed-syscalls.pl
deleted file mode 100644
index 05954a8f363a..000000000000
--- a/tools/perf/scripts/perl/failed-syscalls.pl
+++ /dev/null
@@ -1,47 +0,0 @@
-# failed system call counts
-# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
-# Licensed under the terms of the GNU GPL License version 2
-#
-# Displays system-wide failed system call totals
-# If a [comm] arg is specified, only syscalls called by [comm] are displayed.
-
-use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
-use lib "./Perf-Trace-Util/lib";
-use Perf::Trace::Core;
-use Perf::Trace::Context;
-use Perf::Trace::Util;
-
-my $for_comm = shift;
-
-my %failed_syscalls;
-
-sub raw_syscalls::sys_exit
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $id, $ret) = @_;
-
- if ($ret < 0) {
- $failed_syscalls{$common_comm}++;
- }
-}
-
-sub syscalls::sys_exit
-{
- raw_syscalls::sys_exit(@_)
-}
-
-sub trace_end
-{
- printf("\nfailed syscalls by comm:\n\n");
-
- printf("%-20s %10s\n", "comm", "# errors");
- printf("%-20s %6s %10s\n", "--------------------", "----------");
-
- foreach my $comm (sort {$failed_syscalls{$b} <=> $failed_syscalls{$a}}
- keys %failed_syscalls) {
- next if ($for_comm && $comm ne $for_comm);
-
- printf("%-20s %10s\n", $comm, $failed_syscalls{$comm});
- }
-}
diff --git a/tools/perf/scripts/perl/rw-by-file.pl b/tools/perf/scripts/perl/rw-by-file.pl
deleted file mode 100644
index 92a750b8552b..000000000000
--- a/tools/perf/scripts/perl/rw-by-file.pl
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/perl -w
-# SPDX-License-Identifier: GPL-2.0-only
-# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
-
-# Display r/w activity for files read/written to for a given program
-
-# The common_* event handler fields are the most useful fields common to
-# all events. They don't necessarily correspond to the 'common_*' fields
-# in the status files. Those fields not available as handler params can
-# be retrieved via script functions of the form get_common_*().
-
-use 5.010000;
-use strict;
-use warnings;
-
-use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
-use lib "./Perf-Trace-Util/lib";
-use Perf::Trace::Core;
-use Perf::Trace::Util;
-
-my $usage = "perf script -s rw-by-file.pl <comm>\n";
-
-my $for_comm = shift or die $usage;
-
-my %reads;
-my %writes;
-
-sub syscalls::sys_enter_read
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain, $nr, $fd, $buf, $count) = @_;
-
- if ($common_comm eq $for_comm) {
- $reads{$fd}{bytes_requested} += $count;
- $reads{$fd}{total_reads}++;
- }
-}
-
-sub syscalls::sys_enter_write
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain, $nr, $fd, $buf, $count) = @_;
-
- if ($common_comm eq $for_comm) {
- $writes{$fd}{bytes_written} += $count;
- $writes{$fd}{total_writes}++;
- }
-}
-
-sub trace_end
-{
- printf("file read counts for $for_comm:\n\n");
-
- printf("%6s %10s %10s\n", "fd", "# reads", "bytes_requested");
- printf("%6s %10s %10s\n", "------", "----------", "-----------");
-
- foreach my $fd (sort {$reads{$b}{bytes_requested} <=>
- $reads{$a}{bytes_requested}} keys %reads) {
- my $total_reads = $reads{$fd}{total_reads};
- my $bytes_requested = $reads{$fd}{bytes_requested};
- printf("%6u %10u %10u\n", $fd, $total_reads, $bytes_requested);
- }
-
- printf("\nfile write counts for $for_comm:\n\n");
-
- printf("%6s %10s %10s\n", "fd", "# writes", "bytes_written");
- printf("%6s %10s %10s\n", "------", "----------", "-----------");
-
- foreach my $fd (sort {$writes{$b}{bytes_written} <=>
- $writes{$a}{bytes_written}} keys %writes) {
- my $total_writes = $writes{$fd}{total_writes};
- my $bytes_written = $writes{$fd}{bytes_written};
- printf("%6u %10u %10u\n", $fd, $total_writes, $bytes_written);
- }
-
- print_unhandled();
-}
-
-my %unhandled;
-
-sub print_unhandled
-{
- if ((scalar keys %unhandled) == 0) {
- return;
- }
-
- print "\nunhandled events:\n\n";
-
- printf("%-40s %10s\n", "event", "count");
- printf("%-40s %10s\n", "----------------------------------------",
- "-----------");
-
- foreach my $event_name (keys %unhandled) {
- printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
- }
-}
-
-sub trace_unhandled
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain) = @_;
-
- $unhandled{$event_name}++;
-}
-
-
diff --git a/tools/perf/scripts/perl/rw-by-pid.pl b/tools/perf/scripts/perl/rw-by-pid.pl
deleted file mode 100644
index d789fe39caab..000000000000
--- a/tools/perf/scripts/perl/rw-by-pid.pl
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/perl -w
-# SPDX-License-Identifier: GPL-2.0-only
-# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
-
-# Display r/w activity for all processes
-
-# The common_* event handler fields are the most useful fields common to
-# all events. They don't necessarily correspond to the 'common_*' fields
-# in the status files. Those fields not available as handler params can
-# be retrieved via script functions of the form get_common_*().
-
-use 5.010000;
-use strict;
-use warnings;
-
-use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
-use lib "./Perf-Trace-Util/lib";
-use Perf::Trace::Core;
-use Perf::Trace::Util;
-
-my %reads;
-my %writes;
-
-sub syscalls::sys_exit_read
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $ret) = @_;
-
- if ($ret > 0) {
- $reads{$common_pid}{bytes_read} += $ret;
- } else {
- if (!defined ($reads{$common_pid}{bytes_read})) {
- $reads{$common_pid}{bytes_read} = 0;
- }
- $reads{$common_pid}{errors}{$ret}++;
- }
-}
-
-sub syscalls::sys_enter_read
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $fd, $buf, $count) = @_;
-
- $reads{$common_pid}{bytes_requested} += $count;
- $reads{$common_pid}{total_reads}++;
- $reads{$common_pid}{comm} = $common_comm;
-}
-
-sub syscalls::sys_exit_write
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $ret) = @_;
-
- if ($ret <= 0) {
- $writes{$common_pid}{errors}{$ret}++;
- }
-}
-
-sub syscalls::sys_enter_write
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $fd, $buf, $count) = @_;
-
- $writes{$common_pid}{bytes_written} += $count;
- $writes{$common_pid}{total_writes}++;
- $writes{$common_pid}{comm} = $common_comm;
-}
-
-sub trace_end
-{
- printf("read counts by pid:\n\n");
-
- printf("%6s %20s %10s %10s %10s\n", "pid", "comm",
- "# reads", "bytes_requested", "bytes_read");
- printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------",
- "-----------", "----------", "----------");
-
- foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=>
- ($reads{$a}{bytes_read} || 0) } keys %reads) {
- my $comm = $reads{$pid}{comm} || "";
- my $total_reads = $reads{$pid}{total_reads} || 0;
- my $bytes_requested = $reads{$pid}{bytes_requested} || 0;
- my $bytes_read = $reads{$pid}{bytes_read} || 0;
-
- printf("%6s %-20s %10s %10s %10s\n", $pid, $comm,
- $total_reads, $bytes_requested, $bytes_read);
- }
-
- printf("\nfailed reads by pid:\n\n");
-
- printf("%6s %20s %6s %10s\n", "pid", "comm", "error #", "# errors");
- printf("%6s %20s %6s %10s\n", "------", "--------------------",
- "------", "----------");
-
- my @errcounts = ();
-
- foreach my $pid (keys %reads) {
- foreach my $error (keys %{$reads{$pid}{errors}}) {
- my $comm = $reads{$pid}{comm} || "";
- my $errcount = $reads{$pid}{errors}{$error} || 0;
- push @errcounts, [$pid, $comm, $error, $errcount];
- }
- }
-
- @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts;
-
- for my $i (0 .. $#errcounts) {
- printf("%6d %-20s %6d %10s\n", $errcounts[$i][0],
- $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]);
- }
-
- printf("\nwrite counts by pid:\n\n");
-
- printf("%6s %20s %10s %10s\n", "pid", "comm",
- "# writes", "bytes_written");
- printf("%6s %-20s %10s %10s\n", "------", "--------------------",
- "-----------", "----------");
-
- foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=>
- ($writes{$a}{bytes_written} || 0)} keys %writes) {
- my $comm = $writes{$pid}{comm} || "";
- my $total_writes = $writes{$pid}{total_writes} || 0;
- my $bytes_written = $writes{$pid}{bytes_written} || 0;
-
- printf("%6s %-20s %10s %10s\n", $pid, $comm,
- $total_writes, $bytes_written);
- }
-
- printf("\nfailed writes by pid:\n\n");
-
- printf("%6s %20s %6s %10s\n", "pid", "comm", "error #", "# errors");
- printf("%6s %20s %6s %10s\n", "------", "--------------------",
- "------", "----------");
-
- @errcounts = ();
-
- foreach my $pid (keys %writes) {
- foreach my $error (keys %{$writes{$pid}{errors}}) {
- my $comm = $writes{$pid}{comm} || "";
- my $errcount = $writes{$pid}{errors}{$error} || 0;
- push @errcounts, [$pid, $comm, $error, $errcount];
- }
- }
-
- @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts;
-
- for my $i (0 .. $#errcounts) {
- printf("%6d %-20s %6d %10s\n", $errcounts[$i][0],
- $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]);
- }
-
- print_unhandled();
-}
-
-my %unhandled;
-
-sub print_unhandled
-{
- if ((scalar keys %unhandled) == 0) {
- return;
- }
-
- print "\nunhandled events:\n\n";
-
- printf("%-40s %10s\n", "event", "count");
- printf("%-40s %10s\n", "----------------------------------------",
- "-----------");
-
- foreach my $event_name (keys %unhandled) {
- printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
- }
-}
-
-sub trace_unhandled
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain) = @_;
-
- $unhandled{$event_name}++;
-}
diff --git a/tools/perf/scripts/perl/rwtop.pl b/tools/perf/scripts/perl/rwtop.pl
deleted file mode 100644
index eba4df67af6b..000000000000
--- a/tools/perf/scripts/perl/rwtop.pl
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/perl -w
-# SPDX-License-Identifier: GPL-2.0-only
-# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
-
-# read/write top
-#
-# Periodically displays system-wide r/w call activity, broken down by
-# pid. If an [interval] arg is specified, the display will be
-# refreshed every [interval] seconds. The default interval is 3
-# seconds.
-
-use 5.010000;
-use strict;
-use warnings;
-
-use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
-use lib "./Perf-Trace-Util/lib";
-use Perf::Trace::Core;
-use Perf::Trace::Util;
-use POSIX qw/SIGALRM SA_RESTART/;
-
-my $default_interval = 3;
-my $nlines = 20;
-my $print_thread;
-my $print_pending = 0;
-
-my %reads;
-my %writes;
-
-my $interval = shift;
-if (!$interval) {
- $interval = $default_interval;
-}
-
-sub syscalls::sys_exit_read
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $ret) = @_;
-
- print_check();
-
- if ($ret > 0) {
- $reads{$common_pid}{bytes_read} += $ret;
- } else {
- if (!defined ($reads{$common_pid}{bytes_read})) {
- $reads{$common_pid}{bytes_read} = 0;
- }
- $reads{$common_pid}{errors}{$ret}++;
- }
-}
-
-sub syscalls::sys_enter_read
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $fd, $buf, $count) = @_;
-
- print_check();
-
- $reads{$common_pid}{bytes_requested} += $count;
- $reads{$common_pid}{total_reads}++;
- $reads{$common_pid}{comm} = $common_comm;
-}
-
-sub syscalls::sys_exit_write
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $ret) = @_;
-
- print_check();
-
- if ($ret <= 0) {
- $writes{$common_pid}{errors}{$ret}++;
- }
-}
-
-sub syscalls::sys_enter_write
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $nr, $fd, $buf, $count) = @_;
-
- print_check();
-
- $writes{$common_pid}{bytes_written} += $count;
- $writes{$common_pid}{total_writes}++;
- $writes{$common_pid}{comm} = $common_comm;
-}
-
-sub trace_begin
-{
- my $sa = POSIX::SigAction->new(\&set_print_pending);
- $sa->flags(SA_RESTART);
- $sa->safe(1);
- POSIX::sigaction(SIGALRM, $sa) or die "Can't set SIGALRM handler: $!\n";
- alarm 1;
-}
-
-sub trace_end
-{
- print_unhandled();
- print_totals();
-}
-
-sub print_check()
-{
- if ($print_pending == 1) {
- $print_pending = 0;
- print_totals();
- }
-}
-
-sub set_print_pending()
-{
- $print_pending = 1;
- alarm $interval;
-}
-
-sub print_totals
-{
- my $count;
-
- $count = 0;
-
- clear_term();
-
- printf("\nread counts by pid:\n\n");
-
- printf("%6s %20s %10s %10s %10s\n", "pid", "comm",
- "# reads", "bytes_req", "bytes_read");
- printf("%6s %-20s %10s %10s %10s\n", "------", "--------------------",
- "----------", "----------", "----------");
-
- foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=>
- ($reads{$a}{bytes_read} || 0) } keys %reads) {
- my $comm = $reads{$pid}{comm} || "";
- my $total_reads = $reads{$pid}{total_reads} || 0;
- my $bytes_requested = $reads{$pid}{bytes_requested} || 0;
- my $bytes_read = $reads{$pid}{bytes_read} || 0;
-
- printf("%6s %-20s %10s %10s %10s\n", $pid, $comm,
- $total_reads, $bytes_requested, $bytes_read);
-
- if (++$count == $nlines) {
- last;
- }
- }
-
- $count = 0;
-
- printf("\nwrite counts by pid:\n\n");
-
- printf("%6s %20s %10s %13s\n", "pid", "comm",
- "# writes", "bytes_written");
- printf("%6s %-20s %10s %13s\n", "------", "--------------------",
- "----------", "-------------");
-
- foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=>
- ($writes{$a}{bytes_written} || 0)} keys %writes) {
- my $comm = $writes{$pid}{comm} || "";
- my $total_writes = $writes{$pid}{total_writes} || 0;
- my $bytes_written = $writes{$pid}{bytes_written} || 0;
-
- printf("%6s %-20s %10s %13s\n", $pid, $comm,
- $total_writes, $bytes_written);
-
- if (++$count == $nlines) {
- last;
- }
- }
-
- %reads = ();
- %writes = ();
-}
-
-my %unhandled;
-
-sub print_unhandled
-{
- if ((scalar keys %unhandled) == 0) {
- return;
- }
-
- print "\nunhandled events:\n\n";
-
- printf("%-40s %10s\n", "event", "count");
- printf("%-40s %10s\n", "----------------------------------------",
- "-----------");
-
- foreach my $event_name (keys %unhandled) {
- printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
- }
-}
-
-sub trace_unhandled
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain) = @_;
-
- $unhandled{$event_name}++;
-}
diff --git a/tools/perf/scripts/perl/wakeup-latency.pl b/tools/perf/scripts/perl/wakeup-latency.pl
deleted file mode 100644
index 53444ff4ec7f..000000000000
--- a/tools/perf/scripts/perl/wakeup-latency.pl
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/perl -w
-# SPDX-License-Identifier: GPL-2.0-only
-# (c) 2009, Tom Zanussi <tzanussi@gmail.com>
-
-# Display avg/min/max wakeup latency
-
-# The common_* event handler fields are the most useful fields common to
-# all events. They don't necessarily correspond to the 'common_*' fields
-# in the status files. Those fields not available as handler params can
-# be retrieved via script functions of the form get_common_*().
-
-use 5.010000;
-use strict;
-use warnings;
-
-use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
-use lib "./Perf-Trace-Util/lib";
-use Perf::Trace::Core;
-use Perf::Trace::Util;
-
-my %last_wakeup;
-
-my $max_wakeup_latency;
-my $min_wakeup_latency;
-my $total_wakeup_latency = 0;
-my $total_wakeups = 0;
-
-sub sched::sched_switch
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $prev_comm, $prev_pid, $prev_prio, $prev_state, $next_comm, $next_pid,
- $next_prio) = @_;
-
- my $wakeup_ts = $last_wakeup{$common_cpu}{ts};
- if ($wakeup_ts) {
- my $switch_ts = nsecs($common_secs, $common_nsecs);
- my $wakeup_latency = $switch_ts - $wakeup_ts;
- if ($wakeup_latency > $max_wakeup_latency) {
- $max_wakeup_latency = $wakeup_latency;
- }
- if ($wakeup_latency < $min_wakeup_latency) {
- $min_wakeup_latency = $wakeup_latency;
- }
- $total_wakeup_latency += $wakeup_latency;
- $total_wakeups++;
- }
- $last_wakeup{$common_cpu}{ts} = 0;
-}
-
-sub sched::sched_wakeup
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain,
- $comm, $pid, $prio, $success, $target_cpu) = @_;
-
- $last_wakeup{$target_cpu}{ts} = nsecs($common_secs, $common_nsecs);
-}
-
-sub trace_begin
-{
- $min_wakeup_latency = 1000000000;
- $max_wakeup_latency = 0;
-}
-
-sub trace_end
-{
- printf("wakeup_latency stats:\n\n");
- print "total_wakeups: $total_wakeups\n";
- if ($total_wakeups) {
- printf("avg_wakeup_latency (ns): %u\n",
- avg($total_wakeup_latency, $total_wakeups));
- } else {
- printf("avg_wakeup_latency (ns): N/A\n");
- }
- printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency);
- printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency);
-
- print_unhandled();
-}
-
-my %unhandled;
-
-sub print_unhandled
-{
- if ((scalar keys %unhandled) == 0) {
- return;
- }
-
- print "\nunhandled events:\n\n";
-
- printf("%-40s %10s\n", "event", "count");
- printf("%-40s %10s\n", "----------------------------------------",
- "-----------");
-
- foreach my $event_name (keys %unhandled) {
- printf("%-40s %10d\n", $event_name, $unhandled{$event_name});
- }
-}
-
-sub trace_unhandled
-{
- my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
- $common_pid, $common_comm, $common_callchain) = @_;
-
- $unhandled{$event_name}++;
-}
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index b5eaf326573c..8fa2c4d58b8b 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -76,7 +76,6 @@ make_no_jevents := NO_JEVENTS=1
make_jevents_all := JEVENTS_ARCH=all
make_no_bpf_skel := BUILD_BPF_SKEL=0
make_gen_vmlinux_h := GEN_VMLINUX_H=1
-make_libperl := LIBPERL=1
make_no_python_module := NO_PYTHON_MODULE=1
make_no_scripts := NO_PYTHON_MODULE=1
make_no_slang := NO_SLANG=1
@@ -149,7 +148,6 @@ run += make_no_jevents
run += make_jevents_all
run += make_no_bpf_skel
run += make_gen_vmlinux_h
-run += make_libperl
run += make_no_python_module
run += make_no_scripts
run += make_no_slang
diff --git a/tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh b/tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh
index 2c04249a3496..d298b18154b2 100755
--- a/tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh
+++ b/tools/perf/tests/shell/coresight/test_arm_coresight_disasm.sh
@@ -20,13 +20,6 @@ skip_if_no_cs_etm_event || exit 2
set -e
glb_err=1
-# Relative path works whether it's installed or running from repo
-if [ -n "$PERF_EXEC_PATH" ] && [ -e "$PERF_EXEC_PATH/python/arm-cs-trace-disasm.py" ]; then
- script_path="$PERF_EXEC_PATH/python/arm-cs-trace-disasm.py"
-else
- script_path=$(dirname "$0")/../../../python/arm-cs-trace-disasm.py
-fi
-
# shellcheck source=lib/setup_python.sh
. "$(dirname "$0")"/../lib/setup_python.sh
$PYTHON -c "import perf" 2>/dev/null || {
@@ -56,8 +49,8 @@ branch_search='[[:space:]](bl|b(\.(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)
if [ "$(id -u)" == 0 ] && [ -e /proc/kcore ]; then
echo "Testing kernel disassembly"
perf record -o ${perfdata} -e cs_etm//k --kcore -Se -m,64K -- touch $file > /dev/null 2>&1
- $PYTHON ${script_path} -i ${perfdata} --itrace=b -d --stop-sample=2 \
- -k ${perfdata}/kcore_dir/kcore 2> /dev/null > ${file}
+ perf script -i ${perfdata} arm-cs-trace-disasm -- \
+ -d --stop-sample=2 -k ${perfdata}/kcore_dir/kcore 2> /dev/null > ${file}
grep -q -E ${branch_search} ${file}
echo "Found kernel branches"
else
@@ -68,7 +61,8 @@ fi
## Test user ##
echo "Testing userspace disassembly"
perf record -o ${perfdata} -e cs_etm//u -Se -m,64K -- touch $file > /dev/null 2>&1
-$PYTHON ${script_path} -i ${perfdata} -d --stop-sample=2 2> /dev/null > ${file}
+perf script -i ${perfdata} arm-cs-trace-disasm -- \
+ -d --stop-sample=2 2> /dev/null > ${file}
grep -q -E ${branch_search} ${file}
echo "Found userspace branches"
diff --git a/tools/perf/tests/shell/script_perl.sh b/tools/perf/tests/shell/script_perl.sh
deleted file mode 100755
index b6d65b6fbda1..000000000000
--- a/tools/perf/tests/shell/script_perl.sh
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/bash
-# perf script perl tests
-# SPDX-License-Identifier: GPL-2.0
-
-set -e
-
-# set PERF_EXEC_PATH to find scripts in the source directory
-perfdir=$(dirname "$0")/../..
-if [ -e "$perfdir/scripts/perl/Perf-Trace-Util" ]; then
- export PERF_EXEC_PATH=$perfdir
-fi
-
-
-perfdata=$(mktemp /tmp/__perf_test_script_perl.perf.data.XXXXX)
-generated_script=$(mktemp /tmp/__perf_test_script.XXXXX.pl)
-
-cleanup() {
- rm -f "${perfdata}"
- rm -f "${generated_script}"
- trap - EXIT TERM INT
-}
-
-trap_cleanup() {
- echo "Unexpected signal in ${FUNCNAME[1]}"
- cleanup
- exit 1
-}
-trap trap_cleanup TERM INT
-trap cleanup EXIT
-
-check_perl_support() {
- if perf check feature -q libperl; then
- return 0
- fi
- echo "perf script perl test [Skipped: no libperl support]"
- return 2
-}
-
-test_script() {
- local event_name=$1
- local expected_output=$2
- local record_opts=$3
-
- echo "Testing event: $event_name"
-
- # Try to record. If this fails, it might be permissions or lack of support.
- # We return 2 to indicate "skip this event" rather than "fail test".
- if ! perf record -o "${perfdata}" -e "$event_name" $record_opts -- perf test -w thloop > /dev/null 2>&1; then
- echo "perf script perl test [Skipped: failed to record $event_name]"
- return 2
- fi
-
- echo "Generating perl script..."
- if ! perf script -i "${perfdata}" -g "${generated_script}"; then
- echo "perf script perl test [Failed: script generation for $event_name]"
- return 1
- fi
-
- if [ ! -f "${generated_script}" ]; then
- echo "perf script perl test [Failed: script not generated for $event_name]"
- return 1
- fi
-
- echo "Executing perl script..."
- output=$(perf script -i "${perfdata}" -s "${generated_script}" 2>&1)
-
- if echo "$output" | grep -q "$expected_output"; then
- echo "perf script perl test [Success: $event_name triggered $expected_output]"
- return 0
- else
- echo "perf script perl test [Failed: $event_name did not trigger $expected_output]"
- echo "Output was:"
- echo "$output" | head -n 20
- return 1
- fi
-}
-
-check_perl_support || exit 2
-
-# Try tracepoint first
-test_script "sched:sched_switch" "sched::sched_switch" "-c 1" && res=0 || res=$?
-
-if [ $res -eq 0 ]; then
- exit 0
-elif [ $res -eq 1 ]; then
- exit 1
-fi
-
-# If tracepoint skipped (res=2), try task-clock
-# For generic events like task-clock, the generated script uses process_event()
-# which dumps data using Data::Dumper. We check for "$VAR1" which is standard Dumper output.
-test_script "task-clock" "\$VAR1" "-c 100" && res=0 || res=$?
-
-if [ $res -eq 0 ]; then
- exit 0
-elif [ $res -eq 1 ]; then
- exit 1
-fi
-
-# If both skipped
-echo "perf script perl test [Skipped: Could not record tracepoint or task-clock]"
-exit 2
diff --git a/tools/perf/tests/shell/test_check_perf_trace_python.sh b/tools/perf/tests/shell/test_check_perf_trace_python.sh
index a346e45eb18c..92cc7b1f0033 100755
--- a/tools/perf/tests/shell/test_check_perf_trace_python.sh
+++ b/tools/perf/tests/shell/test_check_perf_trace_python.sh
@@ -68,7 +68,7 @@ test_file_mode() {
fi
# Run the script
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script check-perf-trace -i "${temp_data}" > "${temp_out}"; then
echo "File mode test failed."
err=1
elif ! grep -q "in trace_begin" "${temp_out}" || \
diff --git a/tools/perf/tests/shell/test_compaction_times_python.sh b/tools/perf/tests/shell/test_compaction_times_python.sh
index ad950f3602b5..50397afaafed 100755
--- a/tools/perf/tests/shell/test_compaction_times_python.sh
+++ b/tools/perf/tests/shell/test_compaction_times_python.sh
@@ -58,7 +58,7 @@ test_file_mode() {
fi
# Run the script with some filters to validate filtering logic
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script compaction-times -i "${temp_data}" > "${temp_out}"; then
echo "File mode default test failed."
err=1
elif ! grep -q "total:" "${temp_out}"; then
@@ -66,7 +66,7 @@ test_file_mode() {
err=1
fi
- if ! "$PYTHON" "$script_path" -i "${temp_data}" "0-0" > "${temp_out}"; then
+ if ! perf script compaction-times -i "${temp_data}" "0-0" > "${temp_out}"; then
echo "File mode strict PID filter test failed."
err=1
elif ! grep -q "total:" "${temp_out}"; then
@@ -74,7 +74,7 @@ test_file_mode() {
err=1
fi
- if ! "$PYTHON" "$script_path" -i "${temp_data}" "sleep" > "${temp_out}"; then
+ if ! perf script compaction-times -i "${temp_data}" "sleep" > "${temp_out}"; then
echo "File mode comm filter test failed."
err=1
elif ! grep -q "total:" "${temp_out}"; then
diff --git a/tools/perf/tests/shell/test_event_analyzing_sample_python.sh b/tools/perf/tests/shell/test_event_analyzing_sample_python.sh
index 4678edfd9e5b..a7a8ded003db 100755
--- a/tools/perf/tests/shell/test_event_analyzing_sample_python.sh
+++ b/tools/perf/tests/shell/test_event_analyzing_sample_python.sh
@@ -45,7 +45,8 @@ test_file_mode() {
fi
# Run the script
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -d "${temp_db}" > "${temp_dir}/perf.out" 2>&1; then
+ if ! perf script event_analyzing_sample -i "${temp_data}" \
+ -d "${temp_db}" > "${temp_dir}/perf.out" 2>&1; then
echo "File mode test failed."
err=1
elif ! grep -q "Statistics about the general events" "${temp_dir}/perf.out" || \
diff --git a/tools/perf/tests/shell/test_export_to_postgresql_python.sh b/tools/perf/tests/shell/test_export_to_postgresql_python.sh
index ce13a1aa7cd7..350813466700 100755
--- a/tools/perf/tests/shell/test_export_to_postgresql_python.sh
+++ b/tools/perf/tests/shell/test_export_to_postgresql_python.sh
@@ -54,7 +54,8 @@ test_file_mode() {
echo "Testing export-to-postgresql.py..."
# Verify that invalid URI / key-value database names are rejected
- if "$PYTHON" "$script_path" -i /dev/null -o "dbname=foo host=evil" >/dev/null 2>&1; then
+ if perf script export-to-postgresql -i /dev/null \
+ -o "dbname=foo host=evil" >/dev/null 2>&1; then
echo "Connection parameter injection check failed."
err=1
fi
@@ -71,7 +72,7 @@ test_file_mode() {
psql -c "DROP DATABASE IF EXISTS ${temp_db}" postgres >/dev/null 2>&1 || true
# Run the script
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -o "${temp_db}" >/dev/null; then
+ if ! perf script export-to-postgresql -i "${temp_data}" -o "${temp_db}" >/dev/null; then
echo "File mode test failed."
err=1
else
@@ -101,7 +102,8 @@ test_intel_pt() {
fi
# Run the script with --itrace cr to synthesize call_returns
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -o "${temp_db}" --itrace cr >/dev/null; then
+ if ! perf script export-to-postgresql -i "${temp_data}" \
+ -o "${temp_db}" --itrace cr >/dev/null; then
echo "intel_pt file mode test failed."
err=1
else
diff --git a/tools/perf/tests/shell/test_export_to_sqlite_python.sh b/tools/perf/tests/shell/test_export_to_sqlite_python.sh
index 59280d372399..d3c5e22a0754 100755
--- a/tools/perf/tests/shell/test_export_to_sqlite_python.sh
+++ b/tools/perf/tests/shell/test_export_to_sqlite_python.sh
@@ -55,7 +55,7 @@ test_file_mode() {
fi
# Run the script
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -o "${temp_db}" >/dev/null; then
+ if ! perf script export-to-sqlite -i "${temp_data}" -o "${temp_db}" >/dev/null; then
echo "File mode test failed."
err=1
else
@@ -86,7 +86,7 @@ test_intel_pt() {
fi
# Run the script with --itrace cr to synthesize call_returns
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -o "${temp_db}" --itrace cr; then
+ if ! perf script export-to-sqlite -i "${temp_data}" -o "${temp_db}" --itrace cr; then
echo "intel_pt file mode test failed."
err=1
else
diff --git a/tools/perf/tests/shell/test_failed_syscalls_by_pid_python.sh b/tools/perf/tests/shell/test_failed_syscalls_by_pid_python.sh
index 5bbd1a0adb1e..215372d4e1c5 100755
--- a/tools/perf/tests/shell/test_failed_syscalls_by_pid_python.sh
+++ b/tools/perf/tests/shell/test_failed_syscalls_by_pid_python.sh
@@ -63,14 +63,14 @@ test_file_mode() {
fi
# Run the script and check output
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script failed-syscalls-by-pid -i "${temp_data}" > "${temp_out}"; then
echo "failed-syscalls-by-pid test failed."
err=1
elif ! grep -n -q "err = ENOENT" "${temp_out}"; then
echo "Failed to find expected failed syscalls"
cat "${temp_out}"
err=1
- elif ! "$PYTHON" "$script_path" -i "${temp_data}" "ls" > "${temp_out}.comm" || \
+ elif ! perf script failed-syscalls-by-pid -i "${temp_data}" "ls" > "${temp_out}.comm" || \
! grep -q "err = ENOENT" "${temp_out}.comm"; then
echo "failed-syscalls-by-pid comm filter test failed."
cat "${temp_out}.comm"
@@ -78,7 +78,8 @@ test_file_mode() {
else
ls_pid=$(sed -n 's/^ls \[\([0-9][0-9]*\)\].*/\1/p' "${temp_out}.comm" | head -n 1)
if [ -z "${ls_pid}" ] || \
- ! "$PYTHON" "$script_path" -i "${temp_data}" "${ls_pid}" > "${temp_out}.pid" || \
+ ! perf script failed-syscalls-by-pid -i "${temp_data}" \
+ "${ls_pid}" > "${temp_out}.pid" || \
! grep -q "err = ENOENT" "${temp_out}.pid"; then
echo "failed-syscalls-by-pid PID filter test failed."
cat "${temp_out}.pid" 2>/dev/null || true
diff --git a/tools/perf/tests/shell/test_failed_syscalls_python.sh b/tools/perf/tests/shell/test_failed_syscalls_python.sh
index 0cabb127d7e9..861c2ba71c0a 100755
--- a/tools/perf/tests/shell/test_failed_syscalls_python.sh
+++ b/tools/perf/tests/shell/test_failed_syscalls_python.sh
@@ -63,7 +63,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script failed-syscalls -i "${temp_data}" > "${temp_out}"; then
echo "failed-syscalls.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_flamegraph_python.sh b/tools/perf/tests/shell/test_flamegraph_python.sh
index 3733d53b916b..08f4f6598ed3 100755
--- a/tools/perf/tests/shell/test_flamegraph_python.sh
+++ b/tools/perf/tests/shell/test_flamegraph_python.sh
@@ -49,11 +49,11 @@ test_file_mode() {
fi
# Run the script, dump as json to temp_json (testing both file mode and pipe '-' mode)
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -f json -o "${temp_json}" >/dev/null; then
+ if ! perf script flamegraph -i "${temp_data}" -f json -o "${temp_json}" >/dev/null; then
echo "File mode JSON test failed."
err=1
elif ! perf record -g -o - -- perf test -w noploop 2>/dev/null | \
- "$PYTHON" "$script_path" -i - -f json -o "${temp_json}" >/dev/null; then
+ perf script flamegraph -i - -f json -o "${temp_json}" >/dev/null; then
echo "Pipe stdin JSON mode test failed."
err=1
else
@@ -72,7 +72,7 @@ assert d.get('v', 0) > 0 or len(d.get('c', [])) > 0" "${temp_json}" >/dev/null 2
fi
# Run the script, dump as html to temp_html using MINIMAL_HTML fallback
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -f html \
+ if ! perf script flamegraph -i "${temp_data}" -f html \
--template /nonexistent/template.html -o "${temp_html}" >/dev/null 2>&1; then
echo "File mode HTML test failed."
err=1
@@ -93,7 +93,7 @@ const opts = /** @options_json **/;
const data = /** @flamegraph_json **/;
</script></body></html>
EOF
- if ! "$PYTHON" "$script_path" -i "${temp_data}" -f html --template "${temp_tpl}" \
+ if ! perf script flamegraph -i "${temp_data}" -f html --template "${temp_tpl}" \
--colorscheme blue-green -o "${temp_html}" >/dev/null 2>&1; then
echo "Custom template HTML test failed."
err=1
diff --git a/tools/perf/tests/shell/test_futex_contention_python.sh b/tools/perf/tests/shell/test_futex_contention_python.sh
index 26b13d263d20..a8846ed68ac2 100755
--- a/tools/perf/tests/shell/test_futex_contention_python.sh
+++ b/tools/perf/tests/shell/test_futex_contention_python.sh
@@ -101,7 +101,7 @@ test_file_mode() {
return
fi
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script futex-contention -i "${temp_data}" > "${temp_out}"; then
echo "File mode test failed."
err=1
else
diff --git a/tools/perf/tests/shell/test_gecko_python.sh b/tools/perf/tests/shell/test_gecko_python.sh
index eac9b2f8e3c7..de1d7fcf88b7 100755
--- a/tools/perf/tests/shell/test_gecko_python.sh
+++ b/tools/perf/tests/shell/test_gecko_python.sh
@@ -45,7 +45,7 @@ test_file_mode() {
fi
# Run the script in save-only mode with custom product and category colors
- if ! "$PYTHON" "$script_path" -i "${temp_data}" \
+ if ! perf script gecko -i "${temp_data}" \
--product "perf-test-product" --user-color blue --kernel-color red \
--save-only "${temp_json}" >/dev/null; then
echo "File mode test failed."
diff --git a/tools/perf/tests/shell/test_intel_pt_events_python.sh b/tools/perf/tests/shell/test_intel_pt_events_python.sh
index 0d397792ced8..b5c3173fa2db 100755
--- a/tools/perf/tests/shell/test_intel_pt_events_python.sh
+++ b/tools/perf/tests/shell/test_intel_pt_events_python.sh
@@ -49,7 +49,7 @@ test_intel_pt() {
fi
# Run the script and check output
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script intel-pt-events -i "${temp_data}" > "${temp_out}"; then
echo "intel-pt-events.py test failed."
err=1
else
diff --git a/tools/perf/tests/shell/test_mem_phys_addr_python.sh b/tools/perf/tests/shell/test_mem_phys_addr_python.sh
index d094a0611a24..451692d5e089 100755
--- a/tools/perf/tests/shell/test_mem_phys_addr_python.sh
+++ b/tools/perf/tests/shell/test_mem_phys_addr_python.sh
@@ -87,7 +87,8 @@ test_file_mode() {
fi
# Run the script with custom --iomem
- if ! "$PYTHON" "$script_path" -i "${temp_data}" --iomem "${temp_iomem}" > "${temp_out}" || \
+ if ! perf script mem-phys-addr -i "${temp_data}" \
+ --iomem "${temp_iomem}" > "${temp_out}" || \
[ ! -s "${temp_out}" ]; then
echo "File mode test failed."
err=1
diff --git a/tools/perf/tests/shell/test_net_dropmonitor_python.sh b/tools/perf/tests/shell/test_net_dropmonitor_python.sh
index d00be255d259..05056a897bc9 100755
--- a/tools/perf/tests/shell/test_net_dropmonitor_python.sh
+++ b/tools/perf/tests/shell/test_net_dropmonitor_python.sh
@@ -59,7 +59,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes and outputs table header
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script net_dropmonitor -i "${temp_data}" > "${temp_out}"; then
echo "net_dropmonitor.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_netdev_times_python.sh b/tools/perf/tests/shell/test_netdev_times_python.sh
index bb0f8c30207f..393bf446efb2 100755
--- a/tools/perf/tests/shell/test_netdev_times_python.sh
+++ b/tools/perf/tests/shell/test_netdev_times_python.sh
@@ -93,7 +93,7 @@ if ! perf record -e skb:kfree_skb -a -o "${temp_data}" \
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script netdev-times -i "${temp_data}" > "${temp_out}"; then
echo "netdev-times.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_powerpc_hcalls_python.sh b/tools/perf/tests/shell/test_powerpc_hcalls_python.sh
index 5316c28f243f..19569c6d3613 100755
--- a/tools/perf/tests/shell/test_powerpc_hcalls_python.sh
+++ b/tools/perf/tests/shell/test_powerpc_hcalls_python.sh
@@ -79,7 +79,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes on recorded perf.data
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script powerpc-hcalls -i "${temp_data}" > "${temp_out}"; then
echo "powerpc-hcalls.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_rw_by_file_python.sh b/tools/perf/tests/shell/test_rw_by_file_python.sh
index 98218bf8a39e..f121597f418f 100755
--- a/tools/perf/tests/shell/test_rw_by_file_python.sh
+++ b/tools/perf/tests/shell/test_rw_by_file_python.sh
@@ -52,7 +52,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes - filtering for "dd" since that's what we ran
-if ! "$PYTHON" "$script_path" -i "${temp_data}" "dd" > "${temp_out}"; then
+if ! perf script rw-by-file -i "${temp_data}" "dd" > "${temp_out}"; then
echo "rw-by-file.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_rw_by_pid_python.sh b/tools/perf/tests/shell/test_rw_by_pid_python.sh
index da8b065d43de..41eaa29097a2 100755
--- a/tools/perf/tests/shell/test_rw_by_pid_python.sh
+++ b/tools/perf/tests/shell/test_rw_by_pid_python.sh
@@ -58,7 +58,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script rw-by-pid -i "${temp_data}" > "${temp_out}"; then
echo "rw-by-pid.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_rwtop_python.sh b/tools/perf/tests/shell/test_rwtop_python.sh
index 062fca2dad14..05897e384702 100755
--- a/tools/perf/tests/shell/test_rwtop_python.sh
+++ b/tools/perf/tests/shell/test_rwtop_python.sh
@@ -58,7 +58,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script rwtop -i "${temp_data}" > "${temp_out}"; then
echo "rwtop.py test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_sched_migration_python.sh b/tools/perf/tests/shell/test_sched_migration_python.sh
index f243e86c6700..75465bcd3791 100755
--- a/tools/perf/tests/shell/test_sched_migration_python.sh
+++ b/tools/perf/tests/shell/test_sched_migration_python.sh
@@ -58,7 +58,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -v --no-gui -i "${temp_data}" > "${temp_out}"; then
+if ! perf script sched-migration -v --no-gui -i "${temp_data}" > "${temp_out}"; then
echo "sched-migration.py test failed"
err=1
elif [ "$has_sched" -eq 1 ] && ! grep -q "Timeslices:" "${temp_out}"; then
diff --git a/tools/perf/tests/shell/test_sctop_python.sh b/tools/perf/tests/shell/test_sctop_python.sh
index cd38cdd4794c..007f2584cce6 100755
--- a/tools/perf/tests/shell/test_sctop_python.sh
+++ b/tools/perf/tests/shell/test_sctop_python.sh
@@ -56,13 +56,13 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script sctop -i "${temp_data}" > "${temp_out}"; then
echo "sctop.py test failed"
err=1
elif ! grep -E -q "[0-9]+$" "${temp_out}"; then
echo "Failed to find metric data rows in default run"
err=1
-elif ! "$PYTHON" "$script_path" -i "${temp_data}" sleep 1 > "${temp_out}"; then
+elif ! perf script sctop -i "${temp_data}" sleep 1 > "${temp_out}"; then
echo "sctop.py comm+interval test failed"
err=1
else
diff --git a/tools/perf/tests/shell/test_stackcollapse_python.sh b/tools/perf/tests/shell/test_stackcollapse_python.sh
index a3b6c917e842..ce0f80407eec 100755
--- a/tools/perf/tests/shell/test_stackcollapse_python.sh
+++ b/tools/perf/tests/shell/test_stackcollapse_python.sh
@@ -47,7 +47,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes with default options
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script stackcollapse -i "${temp_data}" > "${temp_out}"; then
echo "stackcollapse.py test failed"
err=1
else
@@ -61,12 +61,12 @@ else
fi
# Test CLI flags (--include-pid, --include-tid, --tidy-java, --kernel) and BrokenPipeError
-if ! "$PYTHON" "$script_path" -i "${temp_data}" \
+if ! perf script stackcollapse -i "${temp_data}" \
--include-pid --include-tid --tidy-java --kernel | head -n 1 > "${temp_out}" || \
[ ! -s "${temp_out}" ]; then
echo "stackcollapse.py options/pipe test failed"
err=1
-elif ! "$PYTHON" "$script_path" -i "${temp_data}" --no-comm > "${temp_out}" || \
+elif ! perf script stackcollapse -i "${temp_data}" --no-comm > "${temp_out}" || \
[ ! -s "${temp_out}" ]; then
echo "stackcollapse.py --no-comm test failed"
err=1
diff --git a/tools/perf/tests/shell/test_stat_cpi_python.sh b/tools/perf/tests/shell/test_stat_cpi_python.sh
index 0960afa4c797..fe7562307634 100755
--- a/tools/perf/tests/shell/test_stat_cpi_python.sh
+++ b/tools/perf/tests/shell/test_stat_cpi_python.sh
@@ -62,7 +62,7 @@ test_live_mode() {
ran=1
# Run live mode for 1 interval in the background, give it a tiny sleep, then interrupt
- "$PYTHON" "$script_path" -I 0.1 -p "$workload_pid" > "${temp_out}" &
+ perf script stat-cpi -I 0.1 -p "$workload_pid" > "${temp_out}" &
pid=$!
sleep 0.5
kill -INT "$pid" 2>/dev/null || true
@@ -96,7 +96,7 @@ test_file_mode() {
fi
ran=1
- out=$("$PYTHON" "$script_path" -i "${temp_data}")
+ out=$(perf script stat-cpi -i "${temp_data}")
if ! echo "$out" | grep -q "cpi"; then
echo "File mode test failed."
err=1
diff --git a/tools/perf/tests/shell/test_syscall_counts_by_pid_python.sh b/tools/perf/tests/shell/test_syscall_counts_by_pid_python.sh
index 9f2ad27751a2..45bbdc554c8f 100755
--- a/tools/perf/tests/shell/test_syscall_counts_by_pid_python.sh
+++ b/tools/perf/tests/shell/test_syscall_counts_by_pid_python.sh
@@ -53,7 +53,7 @@ test_file_mode() {
-- sleep 0.5 >/dev/null 2>&1 || \
{ echo "Skipping test, perf record failed"; exit 2; }
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script syscall-counts-by-pid -i "${temp_data}" > "${temp_out}"; then
echo "File mode test failed."
err=1
elif ! grep -E -q "^ [a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then
@@ -64,7 +64,7 @@ test_file_mode() {
fi
# Test with a comm argument
- if ! "$PYTHON" "$script_path" -i "${temp_data}" "sleep" > "${temp_out}"; then
+ if ! perf script syscall-counts-by-pid -i "${temp_data}" "sleep" > "${temp_out}"; then
echo "Comm filter test failed."
err=1
elif ! grep -E -q "^ [a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then
@@ -76,7 +76,8 @@ test_file_mode() {
# Extract sleep PID from "sleep [<pid>]" header and test with a numeric PID filter argument
sleep_pid=$(sed -n 's/^sleep \[\([0-9]\+\)\]$/\1/p' "${temp_out}" | head -n 1)
- if [ -z "${sleep_pid}" ] || ! "$PYTHON" "$script_path" -i "${temp_data}" "${sleep_pid}" > "${temp_out}"; then
+ if [ -z "${sleep_pid}" ] || \
+ ! perf script syscall-counts-by-pid -i "${temp_data}" "${sleep_pid}" > "${temp_out}"; then
echo "PID filter test failed."
err=1
elif ! grep -E -q "^ [a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then
diff --git a/tools/perf/tests/shell/test_syscall_counts_python.sh b/tools/perf/tests/shell/test_syscall_counts_python.sh
index 0c4b75499209..310e05d399f9 100755
--- a/tools/perf/tests/shell/test_syscall_counts_python.sh
+++ b/tools/perf/tests/shell/test_syscall_counts_python.sh
@@ -54,7 +54,7 @@ test_file_mode() {
exit 2
fi
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+ if ! perf script syscall-counts -i "${temp_data}" > "${temp_out}"; then
echo "File mode test failed."
err=1
elif ! grep -E -q "^[a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then
@@ -65,7 +65,7 @@ test_file_mode() {
fi
# Test with a comm argument
- if ! "$PYTHON" "$script_path" -i "${temp_data}" "sleep" > "${temp_out}"; then
+ if ! perf script syscall-counts -i "${temp_data}" "sleep" > "${temp_out}"; then
echo "Comm filter test failed."
err=1
elif ! grep -E -q "^[a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then
diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh
index 3a97d58eec74..f99a637a6099 100755
--- a/tools/perf/tests/shell/test_task_analyzer.sh
+++ b/tools/perf/tests/shell/test_task_analyzer.sh
@@ -11,16 +11,6 @@ csv="$tmpdir/csv"
csvsummary="$tmpdir/csvsummary"
err=0
-# Set up perfdir and PERF_EXEC_PATH
-if [ "x$PERF_EXEC_PATH" = "x" ]; then
- perfdir="$(dirname "$0")/../.."
- if [ -f "$perfdir/python/task-analyzer.py" ]; then
- export PERF_EXEC_PATH="$perfdir"
- fi
-else
- perfdir="$PERF_EXEC_PATH"
-fi
-
# Disable lsan to avoid warnings about python memory leaks.
export ASAN_OPTIONS=detect_leaks=0
@@ -81,17 +71,17 @@ prepare_perf_data() {
# check standard inkvokation with no arguments
test_basic() {
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata}"
+ perf script -i "${perfdata}" task-analyzer > "$out"
+ check_exec_0 "perf script -i ${perfdata} task-analyzer"
find_str_or_fail "Comm" "$out" "${FUNCNAME[0]}"
}
test_ns_rename(){
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" \
+ perf script -i "${perfdata}" task-analyzer \
--ns \
--rename-comms-by-tids 0:random > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--ns \
--rename-comms-by-tids 0:random"
find_str_or_fail "Comm" "$out" "${FUNCNAME[0]}"
@@ -99,20 +89,20 @@ test_ns_rename(){
test_ms_filtertasks_highlight(){
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" \
+ perf script -i "${perfdata}" task-analyzer \
--ms --filter-tasks perf --highlight-tasks perf \
> "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--ms --filter-tasks perf --highlight-tasks perf"
find_str_or_fail "Comm" "$out" "${FUNCNAME[0]}"
}
test_extended_times_timelimit_limittasks() {
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --extended-times \
+ perf script -i "${perfdata}" task-analyzer --extended-times \
--time-limit :99999 \
--limit-to-tasks perf > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--extended-times \
--time-limit :99999 --limit-to-tasks perf"
find_str_or_fail "Out-Out" "$out" "${FUNCNAME[0]}"
@@ -120,30 +110,30 @@ test_extended_times_timelimit_limittasks() {
test_summary() {
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --summary > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} --summary"
+ perf script -i "${perfdata}" task-analyzer --summary > "$out"
+ check_exec_0 "perf script -i ${perfdata} task-analyzer --summary"
find_str_or_fail "Summary" "$out" "${FUNCNAME[0]}"
}
test_summaryextended() {
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --summary-extended > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} --summary-extended"
+ perf script -i "${perfdata}" task-analyzer --summary-extended > "$out"
+ check_exec_0 "perf script -i ${perfdata} task-analyzer --summary-extended"
find_str_or_fail "Inter Task Times" "$out" "${FUNCNAME[0]}"
}
test_summaryonly() {
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --summary-only > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} --summary-only"
+ perf script -i "${perfdata}" task-analyzer --summary-only > "$out"
+ check_exec_0 "perf script -i ${perfdata} task-analyzer --summary-only"
find_str_or_fail "Summary" "$out" "${FUNCNAME[0]}"
}
test_extended_times_summary_ns() {
out="$tmpdir/perf.out"
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --extended-times \
+ perf script -i "${perfdata}" task-analyzer --extended-times \
--summary --ns > "$out"
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--extended-times \
--summary \
--ns"
@@ -152,34 +142,34 @@ test_extended_times_summary_ns() {
}
test_csv() {
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --csv "${csv}" > /dev/null
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} --csv ${csv}"
+ perf script -i "${perfdata}" task-analyzer --csv "${csv}" > /dev/null
+ check_exec_0 "perf script -i ${perfdata} task-analyzer --csv ${csv}"
find_str_or_fail "Comm;" "${csv}" "${FUNCNAME[0]}"
}
test_csv_extended_times() {
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" \
+ perf script -i "${perfdata}" task-analyzer \
--csv "${csv}" \
--extended-times > /dev/null
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--csv ${csv} \
--extended-times"
find_str_or_fail "Out-Out;" "${csv}" "${FUNCNAME[0]}"
}
test_csvsummary() {
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" \
+ perf script -i "${perfdata}" task-analyzer \
--csv-summary "${csvsummary}" > /dev/null
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--csv-summary ${csvsummary}"
find_str_or_fail "Comm;" "${csvsummary}" "${FUNCNAME[0]}"
}
test_csvsummary_extended() {
- $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" \
+ perf script -i "${perfdata}" task-analyzer \
--csv-summary "${csvsummary}" --summary-extended \
>/dev/null
- check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} \
+ check_exec_0 "perf script -i ${perfdata} task-analyzer \
--csv-summary ${csvsummary} --summary-extended"
find_str_or_fail "Out-Out;" "${csvsummary}" "${FUNCNAME[0]}"
}
diff --git a/tools/perf/tests/shell/test_wakeup_latency_python.sh b/tools/perf/tests/shell/test_wakeup_latency_python.sh
index fc39ac117609..cb2571449168 100755
--- a/tools/perf/tests/shell/test_wakeup_latency_python.sh
+++ b/tools/perf/tests/shell/test_wakeup_latency_python.sh
@@ -57,7 +57,7 @@ if [ ! -s "${temp_data}" ]; then
fi
# Check that the script executes
-if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}"; then
+if ! perf script wakeup-latency -i "${temp_data}" > "${temp_out}"; then
echo "wakeup-latency.py test failed"
err=1
else
@@ -71,7 +71,7 @@ fi
# Also test zero-wakeups / unhandled events path to verify division-by-zero protection
if perf record -e cycles -o "${temp_data}" -- perf test -w noploop >/dev/null 2>&1; then
- if ! "$PYTHON" "$script_path" -i "${temp_data}" > "${temp_out}" || \
+ if ! perf script wakeup-latency -i "${temp_data}" > "${temp_out}" || \
! grep -q "avg_wakeup_latency (ns): N/A" "${temp_out}"; then
echo "wakeup-latency zero-wakeups guard test failed"
err=1
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index b8a3383ec02a..d6d09b4a348c 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -86,75 +86,6 @@ static int scripts_config(const char *var, const char *value, void *data)
return 0;
}
-/*
- * Some scripts specify the required events in their "xxx-record" file,
- * this function will check if the events in perf.data match those
- * mentioned in the "xxx-record".
- *
- * Fixme: All existing "xxx-record" are all in good formats "-e event ",
- * which is covered well now. And new parsing code should be added to
- * cover the future complex formats like event groups etc.
- */
-static int check_ev_match(int dir_fd, const char *scriptname, struct perf_session *session)
-{
- char line[BUFSIZ];
- FILE *fp;
-
- {
- char filename[NAME_MAX + 5];
- int fd;
-
- scnprintf(filename, sizeof(filename), "bin/%s-record", scriptname);
- fd = openat(dir_fd, filename, O_RDONLY);
- if (fd == -1)
- return -1;
- fp = fdopen(fd, "r");
- if (!fp)
- return -1;
- }
-
- while (fgets(line, sizeof(line), fp)) {
- char *p = skip_spaces(line);
-
- if (*p == '#')
- continue;
-
- while (strlen(p)) {
- int match, len;
- struct evsel *pos;
- char evname[128];
-
- p = strstr(p, "-e");
- if (!p)
- break;
-
- p += 2;
- p = skip_spaces(p);
- len = strcspn(p, " \t");
- if (!len)
- break;
-
- snprintf(evname, sizeof(evname), "%.*s", (int)len, p);
-
- match = 0;
- evlist__for_each_entry(session->evlist, pos) {
- if (evsel__name_is(pos, evname)) {
- match = 1;
- break;
- }
- }
-
- if (!match) {
- fclose(fp);
- return -1;
- }
- }
- }
-
- fclose(fp);
- return 0;
-}
-
/*
* Return -1 if none is found, otherwise the actual scripts number.
*
@@ -162,95 +93,18 @@ static int check_ev_match(int dir_fd, const char *scriptname, struct perf_sessio
* will list all statically runnable scripts, select one, execute it and
* show the output in a perf browser.
*/
-static int find_scripts(char **scripts_array, char **scripts_path_array, int num,
- int pathlen)
+static int find_scripts(char **scripts_array __maybe_unused,
+ char **scripts_path_array __maybe_unused, int num __maybe_unused,
+ int pathlen __maybe_unused)
{
- int namelen;
- struct dirent *script_dirent, *lang_dirent;
- int scripts_dir_fd, lang_dir_fd;
- DIR *scripts_dir, *lang_dir;
- struct perf_session *session;
- struct perf_data data = {
- .path = input_name,
- .mode = PERF_DATA_MODE_READ,
- };
- char *temp;
int i = 0;
- const char *exec_path = get_argv_exec_path();
-
- session = perf_session__new(&data, NULL);
- if (IS_ERR(session))
- return PTR_ERR(session);
-
- {
- char scripts_path[PATH_MAX];
-
- snprintf(scripts_path, sizeof(scripts_path), "%s/scripts", exec_path);
- scripts_dir_fd = open(scripts_path, O_DIRECTORY);
- }
- if (scripts_dir_fd != -1) {
- scripts_dir = fdopendir(scripts_dir_fd);
- if (scripts_dir) {
- while ((lang_dirent = readdir(scripts_dir)) != NULL) {
- if (lang_dirent->d_type != DT_DIR &&
- (lang_dirent->d_type == DT_UNKNOWN &&
- !is_directory_at(scripts_dir_fd, lang_dirent->d_name)))
- continue;
- if (!strcmp(lang_dirent->d_name, ".") ||
- !strcmp(lang_dirent->d_name, ".."))
- continue;
-
- if (strstr(lang_dirent->d_name, "python"))
- continue;
-
- lang_dir_fd = openat(scripts_dir_fd, lang_dirent->d_name,
- O_DIRECTORY);
- if (lang_dir_fd == -1)
- continue;
- lang_dir = fdopendir(lang_dir_fd);
- if (!lang_dir) {
- close(lang_dir_fd);
- continue;
- }
- while ((script_dirent = readdir(lang_dir)) != NULL) {
- if (script_dirent->d_type == DT_DIR)
- continue;
- if (script_dirent->d_type == DT_UNKNOWN &&
- is_directory_at(lang_dir_fd, script_dirent->d_name))
- continue;
- /* Skip those real time scripts: xxxtop.p[yl] */
- if (strstr(script_dirent->d_name, "top."))
- continue;
- if (i >= num)
- break;
- scnprintf(scripts_path_array[i], pathlen,
- "%s/scripts/%s/%s", exec_path,
- lang_dirent->d_name,
- script_dirent->d_name);
- temp = strrchr(script_dirent->d_name, '.');
- namelen = temp ? (int)(temp - script_dirent->d_name)
- : (int)strlen(script_dirent->d_name);
-
- if (namelen >= SCRIPT_NAMELEN)
- namelen = SCRIPT_NAMELEN - 1;
- snprintf(scripts_array[i], namelen + 1, "%s",
- script_dirent->d_name);
-
- if (check_ev_match(lang_dir_fd, scripts_array[i], session))
- continue;
-
- i++;
- }
- closedir(lang_dir);
- }
- closedir(scripts_dir);
- } else {
- close(scripts_dir_fd);
- }
- }
#ifdef HAVE_PYTHON_MODULE_SUPPORT
{
+ int namelen;
+ struct dirent *script_dirent;
+ char *temp;
+ const char *exec_path = get_argv_exec_path();
char py_scripts_path[PATH_MAX];
int py_scripts_dir_fd;
DIR *py_scripts_dir;
@@ -299,7 +153,6 @@ static int find_scripts(char **scripts_array, char **scripts_path_array, int num
}
}
#endif
- perf_session__delete(session);
return i;
}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 3ea888f4210a..1d63751af4f2 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -95,7 +95,6 @@ perf-util-y += tool_pmu.o
perf-util-y += tp_pmu.o
perf-util-y += svghelper.o
perf-util-y += trace-event-info.o
-perf-util-y += trace-event-scripting.o
perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event.o
perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event-parse.o
perf-util-$(CONFIG_LIBTRACEEVENT) += trace-event-read.o
@@ -236,8 +235,6 @@ endif
perf-util-y += data-convert-json.o
-perf-util-y += scripting-engines/
-
perf-util-$(CONFIG_ZLIB) += zlib.o
perf-util-$(CONFIG_LZMA) += lzma.o
perf-util-$(CONFIG_ZSTD) += zstd.o
diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build
deleted file mode 100644
index 3f1dc10526f8..000000000000
--- a/tools/perf/util/scripting-engines/Build
+++ /dev/null
@@ -1,5 +0,0 @@
-ifeq ($(CONFIG_LIBTRACEEVENT),y)
- perf-util-$(CONFIG_LIBPERL) += trace-event-perl.o
-endif
-
-CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs -Wno-undef -Wno-switch-default -Wno-bad-function-cast -Wno-declaration-after-statement -Wno-switch-enum -Wno-thread-safety-analysis
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
deleted file mode 100644
index 410dc4cd0600..000000000000
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ /dev/null
@@ -1,770 +0,0 @@
-/*
- * trace-event-perl. Feed perf script events to an embedded Perl interpreter.
- *
- * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <linux/bitmap.h>
-#include <linux/time64.h>
-#include <event-parse.h>
-
-#include <stdbool.h>
-/* perl needs the following define, right after including stdbool.h */
-#define HAS_BOOL
-#include <EXTERN.h>
-#include <perl.h>
-
-#include "../callchain.h"
-#include "../dso.h"
-#include "../machine.h"
-#include "../map.h"
-#include "../symbol.h"
-#include "../thread.h"
-#include "../event.h"
-#include "../trace-event.h"
-#include "../evsel.h"
-#include "../debug.h"
-
-void boot_Perf__Trace__Context(pTHX_ CV *cv);
-void boot_DynaLoader(pTHX_ CV *cv);
-typedef PerlInterpreter * INTERP;
-
-void xs_init(pTHX);
-
-void xs_init(pTHX)
-{
- const char *file = __FILE__;
- dXSUB_SYS;
-
- newXS("Perf::Trace::Context::bootstrap", boot_Perf__Trace__Context,
- file);
- newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
-}
-
-INTERP my_perl;
-
-#define TRACE_EVENT_TYPE_MAX \
- ((1 << (sizeof(unsigned short) * 8)) - 1)
-
-extern struct scripting_context *scripting_context;
-
-static char *cur_field_name;
-static int zero_flag_atom;
-
-static void define_symbolic_value(const char *ev_name,
- const char *field_name,
- const char *field_value,
- const char *field_str)
-{
- unsigned long long value;
- dSP;
-
- value = eval_flag(field_value);
-
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
-
- XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
- XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
- XPUSHs(sv_2mortal(newSVuv(value)));
- XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
-
- PUTBACK;
- if (get_cv("main::define_symbolic_value", 0))
- call_pv("main::define_symbolic_value", G_SCALAR);
- SPAGAIN;
- PUTBACK;
- FREETMPS;
- LEAVE;
-}
-
-static void define_symbolic_values(struct tep_print_flag_sym *field,
- const char *ev_name,
- const char *field_name)
-{
- define_symbolic_value(ev_name, field_name, field->value, field->str);
- if (field->next)
- define_symbolic_values(field->next, ev_name, field_name);
-}
-
-static void define_symbolic_field(const char *ev_name,
- const char *field_name)
-{
- dSP;
-
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
-
- XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
- XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
-
- PUTBACK;
- if (get_cv("main::define_symbolic_field", 0))
- call_pv("main::define_symbolic_field", G_SCALAR);
- SPAGAIN;
- PUTBACK;
- FREETMPS;
- LEAVE;
-}
-
-static void define_flag_value(const char *ev_name,
- const char *field_name,
- const char *field_value,
- const char *field_str)
-{
- unsigned long long value;
- dSP;
-
- value = eval_flag(field_value);
-
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
-
- XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
- XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
- XPUSHs(sv_2mortal(newSVuv(value)));
- XPUSHs(sv_2mortal(newSVpv(field_str, 0)));
-
- PUTBACK;
- if (get_cv("main::define_flag_value", 0))
- call_pv("main::define_flag_value", G_SCALAR);
- SPAGAIN;
- PUTBACK;
- FREETMPS;
- LEAVE;
-}
-
-static void define_flag_values(struct tep_print_flag_sym *field,
- const char *ev_name,
- const char *field_name)
-{
- define_flag_value(ev_name, field_name, field->value, field->str);
- if (field->next)
- define_flag_values(field->next, ev_name, field_name);
-}
-
-static void define_flag_field(const char *ev_name,
- const char *field_name,
- const char *delim)
-{
- dSP;
-
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
-
- XPUSHs(sv_2mortal(newSVpv(ev_name, 0)));
- XPUSHs(sv_2mortal(newSVpv(field_name, 0)));
- XPUSHs(sv_2mortal(newSVpv(delim, 0)));
-
- PUTBACK;
- if (get_cv("main::define_flag_field", 0))
- call_pv("main::define_flag_field", G_SCALAR);
- SPAGAIN;
- PUTBACK;
- FREETMPS;
- LEAVE;
-}
-
-static void define_event_symbols(struct tep_event *event,
- const char *ev_name,
- struct tep_print_arg *args)
-{
- if (args == NULL)
- return;
-
- switch (args->type) {
- case TEP_PRINT_NULL:
- break;
- case TEP_PRINT_ATOM:
- define_flag_value(ev_name, cur_field_name, "0",
- args->atom.atom);
- zero_flag_atom = 0;
- break;
- case TEP_PRINT_FIELD:
- free(cur_field_name);
- cur_field_name = strdup(args->field.name);
- break;
- case TEP_PRINT_FLAGS:
- define_event_symbols(event, ev_name, args->flags.field);
- define_flag_field(ev_name, cur_field_name, args->flags.delim);
- define_flag_values(args->flags.flags, ev_name, cur_field_name);
- break;
- case TEP_PRINT_SYMBOL:
- define_event_symbols(event, ev_name, args->symbol.field);
- define_symbolic_field(ev_name, cur_field_name);
- define_symbolic_values(args->symbol.symbols, ev_name,
- cur_field_name);
- break;
- case TEP_PRINT_HEX:
- case TEP_PRINT_HEX_STR:
- define_event_symbols(event, ev_name, args->hex.field);
- define_event_symbols(event, ev_name, args->hex.size);
- break;
- case TEP_PRINT_INT_ARRAY:
- define_event_symbols(event, ev_name, args->int_array.field);
- define_event_symbols(event, ev_name, args->int_array.count);
- define_event_symbols(event, ev_name, args->int_array.el_size);
- break;
- case TEP_PRINT_BSTRING:
- case TEP_PRINT_DYNAMIC_ARRAY:
- case TEP_PRINT_DYNAMIC_ARRAY_LEN:
- case TEP_PRINT_STRING:
- case TEP_PRINT_BITMASK:
- break;
- case TEP_PRINT_TYPE:
- define_event_symbols(event, ev_name, args->typecast.item);
- break;
- case TEP_PRINT_OP:
- if (strcmp(args->op.op, ":") == 0)
- zero_flag_atom = 1;
- define_event_symbols(event, ev_name, args->op.left);
- define_event_symbols(event, ev_name, args->op.right);
- break;
- case TEP_PRINT_FUNC:
- default:
- pr_err("Unsupported print arg type\n");
- /* we should warn... */
- return;
- }
-
- if (args->next)
- define_event_symbols(event, ev_name, args->next);
-}
-
-static SV *perl_process_callchain(struct perf_sample *sample,
- struct addr_location *al)
-{
- struct callchain_cursor *cursor;
- AV *list;
-
- list = newAV();
- if (!list)
- goto exit;
-
- if (!symbol_conf.use_callchain || !sample->callchain)
- goto exit;
-
- cursor = get_tls_callchain_cursor();
-
- if (thread__resolve_callchain(al->thread, cursor,
- sample, NULL, NULL, scripting_max_stack) != 0) {
- pr_err("Failed to resolve callchain. Skipping\n");
- goto exit;
- }
- callchain_cursor_commit(cursor);
-
-
- while (1) {
- HV *elem;
- struct callchain_cursor_node *node;
- node = callchain_cursor_current(cursor);
- if (!node)
- break;
-
- elem = newHV();
- if (!elem)
- goto exit;
-
- if (!hv_stores(elem, "ip", newSVuv(node->ip))) {
- hv_undef(elem);
- goto exit;
- }
-
- if (node->ms.sym) {
- HV *sym = newHV();
- if (!sym) {
- hv_undef(elem);
- goto exit;
- }
- if (!hv_stores(sym, "start", newSVuv(node->ms.sym->start)) ||
- !hv_stores(sym, "end", newSVuv(node->ms.sym->end)) ||
- !hv_stores(sym, "binding", newSVuv(symbol__binding(node->ms.sym))) ||
- !hv_stores(sym, "name", newSVpvn(node->ms.sym->name,
- node->ms.sym->namelen)) ||
- !hv_stores(elem, "sym", newRV_noinc((SV*)sym))) {
- hv_undef(sym);
- hv_undef(elem);
- goto exit;
- }
- }
-
- if (node->ms.map) {
- struct map *map = node->ms.map;
- struct dso *dso = map ? map__dso(map) : NULL;
- const char *dsoname = "[unknown]";
-
- if (dso) {
- if (symbol_conf.show_kernel_path && dso__long_name(dso))
- dsoname = dso__long_name(dso);
- else
- dsoname = dso__name(dso);
- }
- if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) {
- hv_undef(elem);
- goto exit;
- }
- }
-
- callchain_cursor_advance(cursor);
- av_push(list, newRV_noinc((SV*)elem));
- }
-
-exit:
- return newRV_noinc((SV*)list);
-}
-
-static void perl_process_tracepoint(struct perf_sample *sample,
- struct addr_location *al)
-{
- struct thread *thread = al->thread;
- struct tep_event *event;
- struct tep_format_field *field;
- static char handler[256];
- unsigned long long val;
- unsigned long s, ns;
- int pid;
- int cpu = sample->cpu;
- void *data = sample->raw_data;
- unsigned long long nsecs = sample->time;
- const char *comm = thread__comm_str(thread);
- DECLARE_BITMAP(events_defined, TRACE_EVENT_TYPE_MAX);
- struct evsel *evsel = sample->evsel;
-
- bitmap_zero(events_defined, TRACE_EVENT_TYPE_MAX);
- dSP;
-
- if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
- return;
-
- event = evsel__tp_format(evsel);
- if (!event) {
- pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->core.attr.config);
- return;
- }
-
- pid = raw_field_value(event, "common_pid", data);
-
- sprintf(handler, "%s::%s", event->system, event->name);
-
- if (!__test_and_set_bit(event->id, events_defined))
- define_event_symbols(event, handler, event->print_fmt.args);
-
- s = nsecs / NSEC_PER_SEC;
- ns = nsecs - s * NSEC_PER_SEC;
-
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
-
- XPUSHs(sv_2mortal(newSVpv(handler, 0)));
- XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
- XPUSHs(sv_2mortal(newSVuv(cpu)));
- XPUSHs(sv_2mortal(newSVuv(s)));
- XPUSHs(sv_2mortal(newSVuv(ns)));
- XPUSHs(sv_2mortal(newSViv(pid)));
- XPUSHs(sv_2mortal(newSVpv(comm, 0)));
- XPUSHs(sv_2mortal(perl_process_callchain(sample, al)));
-
- /* common fields other than pid can be accessed via xsub fns */
-
- for (field = event->format.fields; field; field = field->next) {
- if (field->flags & TEP_FIELD_IS_STRING) {
- int offset;
- if (field->flags & TEP_FIELD_IS_DYNAMIC) {
- offset = *(int *)(data + field->offset);
- offset &= 0xffff;
- if (tep_field_is_relative(field->flags))
- offset += field->offset + field->size;
- } else
- offset = field->offset;
- XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
- } else { /* FIELD_IS_NUMERIC */
- val = read_size(event, data + field->offset,
- field->size);
- if (field->flags & TEP_FIELD_IS_SIGNED) {
- XPUSHs(sv_2mortal(newSViv(val)));
- } else {
- XPUSHs(sv_2mortal(newSVuv(val)));
- }
- }
- }
-
- PUTBACK;
-
- if (get_cv(handler, 0))
- call_pv(handler, G_SCALAR);
- else if (get_cv("main::trace_unhandled", 0)) {
- XPUSHs(sv_2mortal(newSVpv(handler, 0)));
- XPUSHs(sv_2mortal(newSViv(PTR2IV(scripting_context))));
- XPUSHs(sv_2mortal(newSVuv(cpu)));
- XPUSHs(sv_2mortal(newSVuv(nsecs)));
- XPUSHs(sv_2mortal(newSViv(pid)));
- XPUSHs(sv_2mortal(newSVpv(comm, 0)));
- XPUSHs(sv_2mortal(perl_process_callchain(sample, al)));
- call_pv("main::trace_unhandled", G_SCALAR);
- }
- SPAGAIN;
- PUTBACK;
- FREETMPS;
- LEAVE;
-}
-
-static void perl_process_event_generic(union perf_event *event, struct perf_sample *sample)
-{
- dSP;
-
- if (!get_cv("process_event", 0))
- return;
-
- ENTER;
- SAVETMPS;
- PUSHMARK(SP);
- XPUSHs(sv_2mortal(newSVpvn((const char *)event, event->header.size)));
- XPUSHs(sv_2mortal(newSVpvn((const char *)&sample->evsel->core.attr,
- sizeof(sample->evsel->core.attr))));
- XPUSHs(sv_2mortal(newSVpvn((const char *)sample, sizeof(*sample))));
- XPUSHs(sv_2mortal(newSVpvn((const char *)sample->raw_data, sample->raw_size)));
- PUTBACK;
- call_pv("process_event", G_SCALAR);
- SPAGAIN;
- PUTBACK;
- FREETMPS;
- LEAVE;
-}
-
-static void perl_process_event(union perf_event *event,
- struct perf_sample *sample,
- struct addr_location *al,
- struct addr_location *addr_al)
-{
- scripting_context__update(scripting_context, event, sample, al, addr_al);
- perl_process_tracepoint(sample, al);
- perl_process_event_generic(event, sample);
-}
-
-static void run_start_sub(void)
-{
- dSP; /* access to Perl stack */
- PUSHMARK(SP);
-
- if (get_cv("main::trace_begin", 0))
- call_pv("main::trace_begin", G_DISCARD | G_NOARGS);
-}
-
-/*
- * Start trace script
- */
-static int perl_start_script(const char *script, int argc, const char **argv,
- struct perf_session *session)
-{
- const char **command_line;
- int i, err = 0;
-
- scripting_context->session = session;
-
- command_line = malloc((argc + 2) * sizeof(const char *));
- if (!command_line)
- return -ENOMEM;
-
- command_line[0] = "";
- command_line[1] = script;
- for (i = 2; i < argc + 2; i++)
- command_line[i] = argv[i - 2];
-
- my_perl = perl_alloc();
- perl_construct(my_perl);
-
- if (perl_parse(my_perl, xs_init, argc + 2, (char **)command_line,
- (char **)NULL)) {
- err = -1;
- goto error;
- }
-
- if (perl_run(my_perl)) {
- err = -1;
- goto error;
- }
-
- if (SvTRUE(ERRSV)) {
- err = -1;
- goto error;
- }
-
- run_start_sub();
-
- free(command_line);
- return 0;
-error:
- perl_free(my_perl);
- free(command_line);
-
- return err;
-}
-
-static int perl_flush_script(void)
-{
- return 0;
-}
-
-/*
- * Stop trace script
- */
-static int perl_stop_script(void)
-{
- dSP; /* access to Perl stack */
- PUSHMARK(SP);
-
- if (get_cv("main::trace_end", 0))
- call_pv("main::trace_end", G_DISCARD | G_NOARGS);
-
- perl_destruct(my_perl);
- perl_free(my_perl);
-
- return 0;
-}
-
-static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
-{
- int i, not_first, count, nr_events;
- struct tep_event **all_events;
- struct tep_event *event = NULL;
- struct tep_format_field *f;
- char fname[PATH_MAX];
- FILE *ofp;
-
- sprintf(fname, "%s.pl", outfile);
- ofp = fopen(fname, "w");
- if (ofp == NULL) {
- fprintf(stderr, "couldn't open %s\n", fname);
- return -1;
- }
-
- fprintf(ofp, "# perf script event handlers, "
- "generated by perf script -g perl\n");
-
- fprintf(ofp, "# Licensed under the terms of the GNU GPL"
- " License version 2\n\n");
-
- fprintf(ofp, "# The common_* event handler fields are the most useful "
- "fields common to\n");
-
- fprintf(ofp, "# all events. They don't necessarily correspond to "
- "the 'common_*' fields\n");
-
- fprintf(ofp, "# in the format files. Those fields not available as "
- "handler params can\n");
-
- fprintf(ofp, "# be retrieved using Perl functions of the form "
- "common_*($context).\n");
-
- fprintf(ofp, "# See Context.pm for the list of available "
- "functions.\n\n");
-
- fprintf(ofp, "use lib \"$ENV{'PERF_EXEC_PATH'}/scripts/perl/"
- "Perf-Trace-Util/lib\";\n");
-
- fprintf(ofp, "use lib \"./Perf-Trace-Util/lib\";\n");
- fprintf(ofp, "use Perf::Trace::Core;\n");
- fprintf(ofp, "use Perf::Trace::Context;\n");
- fprintf(ofp, "use Perf::Trace::Util;\n\n");
-
- fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
- fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n");
-
-
- fprintf(ofp, "\n\
-sub print_backtrace\n\
-{\n\
- my $callchain = shift;\n\
- for my $node (@$callchain)\n\
- {\n\
- if(exists $node->{sym})\n\
- {\n\
- printf( \"\\t[\\%%x] \\%%s\\n\", $node->{ip}, $node->{sym}{name});\n\
- }\n\
- else\n\
- {\n\
- printf( \"\\t[\\%%x]\\n\", $node{ip});\n\
- }\n\
- }\n\
-}\n\n\
-");
-
- nr_events = tep_get_events_count(pevent);
- all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
-
- for (i = 0; all_events && i < nr_events; i++) {
- event = all_events[i];
- fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
- fprintf(ofp, "\tmy (");
-
- fprintf(ofp, "$event_name, ");
- fprintf(ofp, "$context, ");
- fprintf(ofp, "$common_cpu, ");
- fprintf(ofp, "$common_secs, ");
- fprintf(ofp, "$common_nsecs,\n");
- fprintf(ofp, "\t $common_pid, ");
- fprintf(ofp, "$common_comm, ");
- fprintf(ofp, "$common_callchain,\n\t ");
-
- not_first = 0;
- count = 0;
-
- for (f = event->format.fields; f; f = f->next) {
- if (not_first++)
- fprintf(ofp, ", ");
- if (++count % 5 == 0)
- fprintf(ofp, "\n\t ");
-
- fprintf(ofp, "$%s", f->name);
- }
- fprintf(ofp, ") = @_;\n\n");
-
- fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
- "$common_secs, $common_nsecs,\n\t "
- "$common_pid, $common_comm, $common_callchain);\n\n");
-
- fprintf(ofp, "\tprintf(\"");
-
- not_first = 0;
- count = 0;
-
- for (f = event->format.fields; f; f = f->next) {
- if (not_first++)
- fprintf(ofp, ", ");
- if (count && count % 4 == 0) {
- fprintf(ofp, "\".\n\t \"");
- }
- count++;
-
- fprintf(ofp, "%s=", f->name);
- if (f->flags & TEP_FIELD_IS_STRING ||
- f->flags & TEP_FIELD_IS_FLAG ||
- f->flags & TEP_FIELD_IS_SYMBOLIC)
- fprintf(ofp, "%%s");
- else if (f->flags & TEP_FIELD_IS_SIGNED)
- fprintf(ofp, "%%d");
- else
- fprintf(ofp, "%%u");
- }
-
- fprintf(ofp, "\\n\",\n\t ");
-
- not_first = 0;
- count = 0;
-
- for (f = event->format.fields; f; f = f->next) {
- if (not_first++)
- fprintf(ofp, ", ");
-
- if (++count % 5 == 0)
- fprintf(ofp, "\n\t ");
-
- if (f->flags & TEP_FIELD_IS_FLAG) {
- if ((count - 1) % 5 != 0) {
- fprintf(ofp, "\n\t ");
- count = 4;
- }
- fprintf(ofp, "flag_str(\"");
- fprintf(ofp, "%s::%s\", ", event->system,
- event->name);
- fprintf(ofp, "\"%s\", $%s)", f->name,
- f->name);
- } else if (f->flags & TEP_FIELD_IS_SYMBOLIC) {
- if ((count - 1) % 5 != 0) {
- fprintf(ofp, "\n\t ");
- count = 4;
- }
- fprintf(ofp, "symbol_str(\"");
- fprintf(ofp, "%s::%s\", ", event->system,
- event->name);
- fprintf(ofp, "\"%s\", $%s)", f->name,
- f->name);
- } else
- fprintf(ofp, "$%s", f->name);
- }
-
- fprintf(ofp, ");\n\n");
-
- fprintf(ofp, "\tprint_backtrace($common_callchain);\n");
-
- fprintf(ofp, "}\n\n");
- }
-
- fprintf(ofp, "sub trace_unhandled\n{\n\tmy ($event_name, $context, "
- "$common_cpu, $common_secs, $common_nsecs,\n\t "
- "$common_pid, $common_comm, $common_callchain) = @_;\n\n");
-
- fprintf(ofp, "\tprint_header($event_name, $common_cpu, "
- "$common_secs, $common_nsecs,\n\t $common_pid, "
- "$common_comm, $common_callchain);\n");
- fprintf(ofp, "\tprint_backtrace($common_callchain);\n");
- fprintf(ofp, "}\n\n");
-
- fprintf(ofp, "sub print_header\n{\n"
- "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
- "\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t "
- "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}\n");
-
- fprintf(ofp,
- "\n# Packed byte string args of process_event():\n"
- "#\n"
- "# $event:\tunion perf_event\tutil/event.h\n"
- "# $attr:\tstruct perf_event_attr\tlinux/perf_event.h\n"
- "# $sample:\tstruct perf_sample\tutil/event.h\n"
- "# $raw_data:\tperf_sample->raw_data\tutil/event.h\n"
- "\n"
- "sub process_event\n"
- "{\n"
- "\tmy ($event, $attr, $sample, $raw_data) = @_;\n"
- "\n"
- "\tmy @event\t= unpack(\"LSS\", $event);\n"
- "\tmy @attr\t= unpack(\"LLQQQQQLLQQ\", $attr);\n"
- "\tmy @sample\t= unpack(\"QLLQQQQQLL\", $sample);\n"
- "\tmy @raw_data\t= unpack(\"C*\", $raw_data);\n"
- "\n"
- "\tuse Data::Dumper;\n"
- "\tprint Dumper \\@event, \\@attr, \\@sample, \\@raw_data;\n"
- "}\n");
-
- fclose(ofp);
-
- fprintf(stderr, "generated Perl script: %s\n", fname);
-
- return 0;
-}
-
-struct scripting_ops perl_scripting_ops = {
- .name = "Perl",
- .dirname = "perl",
- .start_script = perl_start_script,
- .flush_script = perl_flush_script,
- .stop_script = perl_stop_script,
- .process_event = perl_process_event,
- .generate_script = perl_generate_script,
-};
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 9c015fc2bcfb..374cf82fd86e 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -14,71 +14,6 @@
#include <linux/kernel.h>
#include <event-parse.h>
-static int get_common_field(struct scripting_context *context,
- int *offset, int *size, const char *type)
-{
- struct tep_handle *pevent = context->pevent;
- struct tep_event *event;
- struct tep_format_field *field;
-
- if (!*size) {
-
- event = tep_get_first_event(pevent);
- if (!event)
- return 0;
-
- field = tep_find_common_field(event, type);
- if (!field)
- return 0;
- *offset = field->offset;
- *size = field->size;
- }
-
- return tep_read_number(pevent, context->event_data + *offset, *size);
-}
-
-int common_lock_depth(struct scripting_context *context)
-{
- static int offset;
- static int size;
- int ret;
-
- ret = get_common_field(context, &size, &offset,
- "common_lock_depth");
- if (ret < 0)
- return -1;
-
- return ret;
-}
-
-int common_flags(struct scripting_context *context)
-{
- static int offset;
- static int size;
- int ret;
-
- ret = get_common_field(context, &size, &offset,
- "common_flags");
- if (ret < 0)
- return -1;
-
- return ret;
-}
-
-int common_pc(struct scripting_context *context)
-{
- static int offset;
- static int size;
- int ret;
-
- ret = get_common_field(context, &size, &offset,
- "common_preempt_count");
- if (ret < 0)
- return -1;
-
- return ret;
-}
-
unsigned long long
raw_field_value(struct tep_event *event, const char *name, void *data)
{
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
deleted file mode 100644
index c78b317978dd..000000000000
--- a/tools/perf/util/trace-event-scripting.c
+++ /dev/null
@@ -1,398 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * 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>
-#ifdef HAVE_LIBTRACEEVENT
-#include <event-parse.h>
-#endif
-
-#include "debug.h"
-#include "event.h"
-#include "trace-event.h"
-#include "evsel.h"
-#include <linux/perf_event.h>
-#include <linux/zalloc.h>
-#include "util/sample.h"
-
-unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
-
-struct scripting_context *scripting_context;
-
-struct script_spec {
- struct list_head node;
- struct scripting_ops *ops;
- char spec[];
-};
-
-static LIST_HEAD(script_specs);
-
-static struct script_spec *script_spec__new(const char *spec,
- struct scripting_ops *ops)
-{
- struct script_spec *s = malloc(sizeof(*s) + strlen(spec) + 1);
-
- if (s != NULL) {
- strcpy(s->spec, spec);
- s->ops = ops;
- }
-
- return s;
-}
-
-static void script_spec__add(struct script_spec *s)
-{
- list_add_tail(&s->node, &script_specs);
-}
-
-static struct script_spec *script_spec__find(const char *spec)
-{
- struct script_spec *s;
-
- list_for_each_entry(s, &script_specs, node)
- if (strcasecmp(s->spec, spec) == 0)
- return s;
- return NULL;
-}
-
-static int script_spec_register(const char *spec, struct scripting_ops *ops)
-{
- struct script_spec *s;
-
- s = script_spec__find(spec);
- if (s)
- return -1;
-
- s = script_spec__new(spec, ops);
- if (!s)
- return -1;
-
- script_spec__add(s);
- return 0;
-}
-
-struct scripting_ops *script_spec__lookup(const char *spec)
-{
- struct script_spec *s = script_spec__find(spec);
-
- if (!s)
- return NULL;
-
- return s->ops;
-}
-
-int script_spec__for_each(int (*cb)(struct scripting_ops *ops, const char *spec))
-{
- struct script_spec *s;
- int ret = 0;
-
- list_for_each_entry(s, &script_specs, node) {
- ret = cb(s->ops, s->spec);
- if (ret)
- break;
- }
- return ret;
-}
-
-void scripting_context__update(struct scripting_context *c,
- union perf_event *event,
- struct perf_sample *sample,
- struct addr_location *al,
- struct addr_location *addr_al)
-{
-#ifdef HAVE_LIBTRACEEVENT
- const struct tep_event *tp_format = evsel__tp_format(sample->evsel);
-
- c->pevent = tp_format ? tp_format->tep : NULL;
-#else
- c->pevent = NULL;
-#endif
- c->event_data = sample->raw_data;
- c->event = event;
- c->sample = sample;
- c->al = al;
- c->addr_al = addr_al;
-}
-
-static int flush_script_unsupported(void)
-{
- return 0;
-}
-
-static int stop_script_unsupported(void)
-{
- return 0;
-}
-
-static void process_event_unsupported(union perf_event *event __maybe_unused,
- struct perf_sample *sample __maybe_unused,
- struct addr_location *al __maybe_unused,
- struct addr_location *addr_al __maybe_unused)
-{
-}
-
-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");
-}
-
-static int python_start_script_unsupported(const char *script __maybe_unused,
- int argc __maybe_unused,
- const char **argv __maybe_unused,
- struct perf_session *session __maybe_unused)
-{
- print_python_unsupported_msg();
-
- return -1;
-}
-
-static int python_generate_script_unsupported(struct tep_handle *pevent
- __maybe_unused,
- const char *outfile
- __maybe_unused)
-{
- print_python_unsupported_msg();
-
- return -1;
-}
-
-struct scripting_ops python_scripting_unsupported_ops = {
- .name = "Python",
- .dirname = "python",
- .start_script = python_start_script_unsupported,
- .flush_script = flush_script_unsupported,
- .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)
-{
- if (scripting_context == NULL)
- scripting_context = malloc(sizeof(*scripting_context));
-
- 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);
- }
-}
-
-void setup_python_scripting(void)
-{
- register_python_scripting(&python_scripting_unsupported_ops);
-}
-
-#ifdef HAVE_LIBTRACEEVENT
-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");
-}
-
-static int perl_start_script_unsupported(const char *script __maybe_unused,
- int argc __maybe_unused,
- const char **argv __maybe_unused,
- struct perf_session *session __maybe_unused)
-{
- print_perl_unsupported_msg();
-
- return -1;
-}
-
-static int perl_generate_script_unsupported(struct tep_handle *pevent
- __maybe_unused,
- const char *outfile __maybe_unused)
-{
- print_perl_unsupported_msg();
-
- return -1;
-}
-
-struct scripting_ops perl_scripting_unsupported_ops = {
- .name = "Perl",
- .dirname = "perl",
- .start_script = perl_start_script_unsupported,
- .flush_script = flush_script_unsupported,
- .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)
-{
- if (scripting_context == NULL)
- scripting_context = malloc(sizeof(*scripting_context));
-
- 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);
- }
-}
-
-#ifndef HAVE_LIBPERL_SUPPORT
-void setup_perl_scripting(void)
-{
- register_perl_scripting(&perl_scripting_unsupported_ops);
-}
-#else
-extern struct scripting_ops perl_scripting_ops;
-
-void setup_perl_scripting(void)
-{
- register_perl_scripting(&perl_scripting_ops);
-}
-#endif
-#endif
-
-static const struct {
- u32 flags;
- const char *name;
-} sample_flags[] = {
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
- {PERF_IP_FLAG_BRANCH, "jmp"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT,
- "hw int"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMENTRY, "vmentry"},
- {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_VMEXIT, "vmexit"},
- {0, NULL}
-};
-
-static const struct {
- u32 flags;
- const char *name;
-} branch_events[] = {
- {PERF_IP_FLAG_BRANCH_MISS, "miss"},
- {PERF_IP_FLAG_NOT_TAKEN, "not_taken"},
- {0, NULL}
-};
-
-static int sample_flags_to_name(u32 flags, char *str, size_t size)
-{
- int i;
- const char *prefix;
- int pos = 0, ret, ev_idx = 0;
- u32 xf = flags & PERF_ADDITIONAL_STATE_MASK;
- u32 types, events;
- char xs[16] = { 0 };
-
- /* Clear additional state bits */
- flags &= ~PERF_ADDITIONAL_STATE_MASK;
-
- if (flags & PERF_IP_FLAG_TRACE_BEGIN)
- prefix = "tr strt ";
- else if (flags & PERF_IP_FLAG_TRACE_END)
- prefix = "tr end ";
- else
- prefix = "";
-
- ret = snprintf(str + pos, size - pos, "%s", prefix);
- if (ret < 0)
- return ret;
- pos += ret;
-
- flags &= ~(PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END);
-
- types = flags & ~PERF_IP_FLAG_BRANCH_EVENT_MASK;
- for (i = 0; sample_flags[i].name; i++) {
- if (sample_flags[i].flags != types)
- continue;
-
- ret = snprintf(str + pos, size - pos, "%s", sample_flags[i].name);
- if (ret < 0)
- return ret;
- pos += ret;
- break;
- }
-
- events = flags & PERF_IP_FLAG_BRANCH_EVENT_MASK;
- for (i = 0; branch_events[i].name; i++) {
- if (!(branch_events[i].flags & events))
- continue;
-
- ret = snprintf(str + pos, size - pos, !ev_idx ? "/%s" : ",%s",
- branch_events[i].name);
- if (ret < 0)
- return ret;
- pos += ret;
- ev_idx++;
- }
-
- /* Add an end character '/' for events */
- if (ev_idx) {
- ret = snprintf(str + pos, size - pos, "/");
- if (ret < 0)
- return ret;
- pos += ret;
- }
-
- if (!xf)
- return pos;
-
- snprintf(xs, sizeof(xs), "(%s%s%s)",
- flags & PERF_IP_FLAG_IN_TX ? "x" : "",
- flags & PERF_IP_FLAG_INTR_DISABLE ? "D" : "",
- flags & PERF_IP_FLAG_INTR_TOGGLE ? "t" : "");
-
- /* Right align the string if its length is less than the limit */
- if ((pos + strlen(xs)) < SAMPLE_FLAGS_STR_ALIGNED_SIZE)
- ret = snprintf(str + pos, size - pos, "%*s",
- (int)(SAMPLE_FLAGS_STR_ALIGNED_SIZE - ret), xs);
- else
- ret = snprintf(str + pos, size - pos, " %s", xs);
- if (ret < 0)
- return ret;
-
- return pos + ret;
-}
-
-int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz)
-{
- const char *chars = PERF_IP_FLAG_CHARS;
- const size_t n = strlen(PERF_IP_FLAG_CHARS);
- size_t i, pos = 0;
- int ret;
-
- ret = sample_flags_to_name(flags, str, sz);
- if (ret > 0)
- return ret;
-
- for (i = 0; i < n; i++, flags >>= 1) {
- if ((flags & 1) && pos < sz)
- str[pos++] = chars[i];
- }
- for (; i < 32; i++, flags >>= 1) {
- if ((flags & 1) && pos < sz)
- str[pos++] = '?';
- }
- if (pos < sz)
- str[pos] = 0;
-
- return pos;
-}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 720121c74f1d..19f22ac1faf3 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -7,15 +7,9 @@
#include <sys/types.h>
#include <linux/types.h>
-struct evlist;
struct machine;
-struct perf_sample;
-union perf_event;
-struct perf_tool;
-struct thread;
-struct tep_plugin_list;
-struct evsel;
struct tep_format_field;
+struct tep_plugin_list;
struct trace_event {
struct tep_handle *pevent;
@@ -79,70 +73,6 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
int fd, bool temp);
int tracing_data_put(struct tracing_data *tdata);
-
-struct addr_location;
-
-struct perf_session;
-struct perf_stat_config;
-
-struct scripting_ops {
- const char *name;
- const char *dirname; /* For script path .../scripts/<dirname>/... */
- int (*start_script)(const char *script, int argc, const char **argv,
- struct perf_session *session);
- int (*flush_script) (void);
- int (*stop_script) (void);
- void (*process_event) (union perf_event *event,
- struct perf_sample *sample,
- struct addr_location *al,
- struct addr_location *addr_al);
- void (*process_switch)(union perf_event *event,
- struct perf_sample *sample,
- struct machine *machine);
- void (*process_auxtrace_error)(struct perf_session *session,
- union perf_event *event);
- void (*process_stat)(struct perf_stat_config *config,
- struct evsel *evsel, u64 tstamp);
- void (*process_stat_interval)(u64 tstamp);
- void (*process_throttle)(union perf_event *event,
- struct perf_sample *sample,
- struct machine *machine);
- int (*generate_script) (struct tep_handle *pevent, const char *outfile);
-};
-
-extern unsigned int scripting_max_stack;
-
-struct scripting_ops *script_spec__lookup(const char *spec);
-int script_spec__for_each(int (*cb)(struct scripting_ops *ops, const char *spec));
-
-void setup_perl_scripting(void);
-void setup_python_scripting(void);
-
-struct scripting_context {
- struct tep_handle *pevent;
- void *event_data;
- union perf_event *event;
- struct perf_sample *sample;
- struct addr_location *al;
- struct addr_location *addr_al;
- struct perf_session *session;
-};
-
-void scripting_context__update(struct scripting_context *scripting_context,
- union perf_event *event,
- struct perf_sample *sample,
- struct addr_location *al,
- struct addr_location *addr_al);
-
-int common_pc(struct scripting_context *context);
-int common_flags(struct scripting_context *context);
-int common_lock_depth(struct scripting_context *context);
-
-#define SAMPLE_FLAGS_BUF_SIZE 64
-#define SAMPLE_FLAGS_STR_ALIGNED_SIZE 21
-
-int perf_sample__sprintf_flags(u32 flags, char *str, size_t sz);
-
#if defined(LIBTRACEEVENT_VERSION) && LIBTRACEEVENT_VERSION >= MAKE_LIBTRACEEVENT_VERSION(1, 5, 0)
#include <event-parse.h>
--
2.56.0.rc1.310.g51773c2048-goog
next prev parent reply other threads:[~2026-09-23 18:15 UTC|newest]
Thread overview: 410+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-20 5:20 [PATCH v1 00/49] perf: Complete transition to standalone Python scripts Ian Rogers
2026-09-20 5:20 ` [PATCH v1 01/49] perf python: Update syscall format string to optional positional Ian Rogers
2026-09-20 5:28 ` sashiko-bot
2026-09-20 5:20 ` [PATCH v1 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-20 5:30 ` sashiko-bot
2026-09-20 5:20 ` [PATCH v1 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-20 5:31 ` sashiko-bot
2026-09-20 5:20 ` [PATCH v1 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-20 5:32 ` sashiko-bot
2026-09-20 5:20 ` [PATCH v1 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-20 5:26 ` sashiko-bot
2026-09-20 5:20 ` [PATCH v1 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-20 5:26 ` sashiko-bot
2026-09-20 5:20 ` [PATCH v1 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-20 5:35 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
2026-09-20 5:34 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 09/49] perf python: Add Intel PT call_return and itrace capability Ian Rogers
2026-09-20 5:35 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-20 5:32 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
2026-09-20 5:29 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 12/49] perf test: Clean up mypy and pylint issues in shell test libraries Ian Rogers
2026-09-20 5:29 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
2026-09-20 5:31 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 14/49] perf build: Make pylint build test opt-out (NO_PYLINT=1) Ian Rogers
2026-09-20 5:32 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-20 5:32 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-20 5:34 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-20 5:29 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-20 5:30 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-20 5:29 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 20/49] perf python: Port gecko " Ian Rogers
2026-09-20 5:31 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-20 5:35 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-20 5:39 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-20 5:37 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-20 5:34 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-20 5:33 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 26/49] perf python: Port sctop " Ian Rogers
2026-09-20 5:39 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-20 5:36 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-20 5:36 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 29/49] perf python: Port rwtop " Ian Rogers
2026-09-20 5:35 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-20 5:35 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-20 5:37 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-20 5:36 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-20 5:39 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-20 5:36 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-20 5:37 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-20 5:39 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-20 5:37 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-20 5:42 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-20 5:38 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
2026-09-20 5:42 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 41/49] perf test: Migrate Intel PT virtual LBR test to Python API Ian Rogers
2026-09-20 5:38 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-20 5:46 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 43/49] perf python: Port export-to-postgresql " Ian Rogers
2026-09-20 5:39 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 44/49] perf python: Move and clean up exported-sql-viewer.py Ian Rogers
2026-09-20 5:21 ` [PATCH v1 45/49] perf python: Move and clean up parallel-perf.py Ian Rogers
2026-09-20 5:40 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 46/49] perf: Remove libpython support and legacy Python scripts Ian Rogers
2026-09-20 5:21 ` [PATCH v1 47/49] perf Makefile: Update Python script installation path Ian Rogers
2026-09-20 5:41 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 48/49] perf script: Support standalone scripts and remove embedded scripting Ian Rogers
2026-09-20 5:45 ` sashiko-bot
2026-09-20 5:21 ` [PATCH v1 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
2026-09-20 5:37 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 00/49] perf: Complete transition to " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 01/49] perf python: Update syscall format string to optional positional Ian Rogers
2026-09-21 5:26 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-21 5:27 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-21 5:28 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-21 5:27 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-21 5:23 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-21 5:23 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-21 5:33 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
2026-09-21 5:34 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 09/49] perf python: Add Intel PT call_return and itrace capability Ian Rogers
2026-09-21 5:31 ` sashiko-bot
2026-09-22 13:11 ` James Clark
2026-09-22 17:00 ` Ian Rogers
2026-09-21 5:06 ` [PATCH v2 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-21 5:27 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
2026-09-21 5:26 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 12/49] perf test: Clean up mypy and pylint issues in shell test libraries Ian Rogers
2026-09-21 5:26 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
2026-09-21 5:30 ` sashiko-bot
2026-09-22 13:11 ` James Clark
2026-09-22 16:59 ` Ian Rogers
2026-09-21 5:06 ` [PATCH v2 14/49] perf build: Make pylint build test opt-out (NO_PYLINT=1) Ian Rogers
2026-09-21 5:29 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-21 5:28 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-21 5:40 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-21 5:30 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-21 5:32 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-21 5:31 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 20/49] perf python: Port gecko " Ian Rogers
2026-09-21 5:34 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-21 5:36 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-21 5:36 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-21 5:33 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-21 5:38 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-21 5:33 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 26/49] perf python: Port sctop " Ian Rogers
2026-09-21 5:41 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-21 5:39 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-21 5:38 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 29/49] perf python: Port rwtop " Ian Rogers
2026-09-21 5:39 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-21 5:38 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-21 5:42 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-21 5:38 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-21 5:39 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-21 5:41 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-21 5:38 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-21 5:47 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-21 5:44 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-21 5:48 ` sashiko-bot
2026-09-22 13:12 ` James Clark
2026-09-23 5:23 ` Ian Rogers
2026-09-23 8:16 ` James Clark
2026-09-23 9:00 ` Leo Yan
2026-09-23 9:08 ` Leo Yan
2026-09-23 13:16 ` Ian Rogers
2026-09-23 13:40 ` Ian Rogers
2026-09-24 15:41 ` Leo Yan
2026-09-25 21:45 ` Ian Rogers
2026-09-21 5:06 ` [PATCH v2 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-21 5:41 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
2026-09-21 5:42 ` sashiko-bot
2026-09-21 5:06 ` [PATCH v2 41/49] perf test: Migrate Intel PT virtual LBR test to Python API Ian Rogers
2026-09-21 5:42 ` sashiko-bot
2026-09-21 5:07 ` [PATCH v2 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-21 5:46 ` sashiko-bot
2026-09-21 5:07 ` [PATCH v2 43/49] perf python: Port export-to-postgresql " Ian Rogers
2026-09-21 5:49 ` sashiko-bot
2026-09-21 5:07 ` [PATCH v2 44/49] perf python: Move and clean up exported-sql-viewer.py Ian Rogers
2026-09-21 5:07 ` [PATCH v2 45/49] perf python: Move and clean up parallel-perf.py Ian Rogers
2026-09-21 5:45 ` sashiko-bot
2026-09-21 5:07 ` [PATCH v2 46/49] perf: Remove libpython support and legacy Python scripts Ian Rogers
2026-09-21 5:07 ` [PATCH v2 47/49] perf Makefile: Update Python script installation path Ian Rogers
2026-09-21 5:50 ` sashiko-bot
2026-09-21 5:07 ` [PATCH v2 48/49] perf script: Support standalone scripts and remove embedded scripting Ian Rogers
2026-09-21 5:56 ` sashiko-bot
2026-09-21 5:07 ` [PATCH v2 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
2026-09-21 5:45 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 00/49] perf: Complete transition to " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 01/49] perf python: Update syscall helpers and expose arch_strerrno Ian Rogers
2026-09-23 18:23 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-23 18:22 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-23 18:26 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-23 18:22 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-23 18:19 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-23 18:19 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-23 18:20 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
2026-09-23 18:28 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 09/49] perf python: Add Intel PT call_return and itrace capability Ian Rogers
2026-09-23 18:30 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-23 18:22 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
2026-09-23 18:24 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 12/49] perf test: Clean up mypy and pylint issues in shell test libraries Ian Rogers
2026-09-23 18:23 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
2026-09-23 18:25 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 14/49] perf build: Make pylint build test opt-out (NO_PYLINT=1) Ian Rogers
2026-09-23 18:27 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-23 18:26 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-23 18:28 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-23 18:26 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-23 18:30 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-23 18:27 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 20/49] perf python: Port gecko " Ian Rogers
2026-09-23 18:32 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-23 18:32 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-23 18:30 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-23 18:33 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-23 18:33 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-23 18:33 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 26/49] perf python: Port sctop " Ian Rogers
2026-09-23 18:35 ` sashiko-bot
2026-09-23 19:08 ` Ian Rogers
2026-09-23 18:11 ` [PATCH v3 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-23 18:35 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-23 18:36 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 29/49] perf python: Port rwtop " Ian Rogers
2026-09-23 18:36 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-23 18:35 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-23 18:38 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-23 18:35 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-23 18:39 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-23 18:37 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-23 18:39 ` sashiko-bot
2026-09-23 18:11 ` [PATCH v3 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-23 18:39 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-23 18:38 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-23 18:40 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-23 18:39 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
2026-09-23 18:40 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 41/49] perf test: Migrate Intel PT virtual LBR test to Python API Ian Rogers
2026-09-23 18:40 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-23 18:42 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 43/49] perf python: Port export-to-postgresql " Ian Rogers
2026-09-23 18:47 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 44/49] perf python: Move and clean up exported-sql-viewer.py Ian Rogers
2026-09-23 18:12 ` [PATCH v3 45/49] perf python: Move and clean up parallel-perf.py Ian Rogers
2026-09-23 18:41 ` sashiko-bot
2026-09-23 18:12 ` [PATCH v3 46/49] perf: Remove libpython support and legacy Python scripts Ian Rogers
2026-09-23 18:12 ` [PATCH v3 47/49] perf Makefile: Update Python script installation path Ian Rogers
2026-09-23 18:49 ` sashiko-bot
2026-09-23 18:12 ` Ian Rogers [this message]
2026-09-23 18:49 ` [PATCH v3 48/49] perf script: Support standalone scripts and remove embedded scripting sashiko-bot
2026-09-23 19:11 ` Ian Rogers
2026-09-23 18:12 ` [PATCH v3 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
2026-09-23 18:44 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 00/49] perf: Complete transition to " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 01/49] perf python: Update syscall helpers and expose arch_strerrno Ian Rogers
2026-09-26 6:30 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-26 6:32 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-26 6:32 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-26 6:30 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-26 6:26 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-26 6:26 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-26 6:26 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
2026-09-26 6:36 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 09/49] perf python: Add Intel PT call_return and itrace capability Ian Rogers
2026-09-26 6:35 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-26 6:32 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
2026-09-26 6:29 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 12/49] perf test: Clean up mypy and pylint issues in shell test libraries Ian Rogers
2026-09-26 6:29 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
2026-09-26 6:33 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 14/49] perf build: Make pylint build test opt-out (NO_PYLINT=1) Ian Rogers
2026-09-26 6:33 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-26 6:28 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-26 6:31 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-26 6:29 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-26 6:33 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-26 6:30 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 20/49] perf python: Port gecko " Ian Rogers
2026-09-26 6:30 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-26 6:34 ` sashiko-bot
2026-09-26 13:46 ` Ian Rogers
2026-09-26 6:19 ` [PATCH v4 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-26 6:31 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-26 6:29 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-26 6:29 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-26 6:32 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 26/49] perf python: Port sctop " Ian Rogers
2026-09-26 6:30 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-26 6:32 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-26 6:34 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 29/49] perf python: Port rwtop " Ian Rogers
2026-09-26 6:35 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-26 6:33 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-26 6:34 ` sashiko-bot
2026-09-26 6:19 ` [PATCH v4 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-26 6:34 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-26 6:35 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-26 6:33 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-26 6:33 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-26 6:34 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-26 6:34 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-26 6:35 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-26 6:35 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
2026-09-26 6:35 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 41/49] perf test: Migrate Intel PT virtual LBR test to Python API Ian Rogers
2026-09-26 6:36 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-26 6:38 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 43/49] perf python: Port export-to-postgresql " Ian Rogers
2026-09-26 6:37 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 44/49] perf python: Move and clean up exported-sql-viewer.py Ian Rogers
2026-09-26 6:20 ` [PATCH v4 45/49] perf python: Move and clean up parallel-perf.py Ian Rogers
2026-09-26 6:37 ` sashiko-bot
2026-09-26 6:20 ` [PATCH v4 46/49] perf: Remove libpython support and legacy Python scripts Ian Rogers
2026-09-26 18:56 ` Arnaldo Carvalho de Melo
2026-09-26 6:20 ` [PATCH v4 47/49] perf Makefile: Update Python script installation path Ian Rogers
2026-09-26 6:43 ` sashiko-bot
2026-09-26 19:05 ` Arnaldo Carvalho de Melo
2026-09-26 6:20 ` [PATCH v4 48/49] perf script: Support standalone scripts and remove embedded scripting Ian Rogers
2026-09-26 6:42 ` sashiko-bot
2026-09-26 19:17 ` Arnaldo Carvalho de Melo
2026-09-26 6:20 ` [PATCH v4 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
2026-09-26 6:37 ` sashiko-bot
2026-09-26 20:41 ` [PATCH v4 00/49] perf: Complete transition to " Arnaldo Carvalho de Melo
2026-09-26 22:46 ` Ian Rogers
2026-09-26 23:11 ` Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260923181213.3032038-49-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alice.mei.rogers@gmail.com \
--cc=dapeng1.mi@linux.intel.com \
--cc=james.clark@linaro.org \
--cc=leo.yan@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=tmricht@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.