From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: alice.mei.rogers@gmail.com, james.clark@linaro.org,
leo.yan@linux.dev, namhyung@kernel.org, adrian.hunter@intel.com,
dapeng1.mi@linux.intel.com, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, mingo@redhat.com,
peterz@infradead.org, tmricht@linux.ibm.com
Subject: Re: [PATCH v4 48/49] perf script: Support standalone scripts and remove embedded scripting
Date: Sat, 26 Sep 2026 21:17:09 +0200 [thread overview]
Message-ID: <argaNT7NdOd06YdU@x2> (raw)
In-Reply-To: <20260926062029.800743-49-irogers@google.com>
On Fri, Sep 25, 2026 at 11:20:15PM -0700, Ian Rogers wrote:
> 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.
Minor conflict: the removal of the LIBPERL block, I removed it manually,
end result should be the same.
- Arnaldo
> 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 | 1016 +++++++++--------
> 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, 607 insertions(+), 3612 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 6c0071db8523..6e92f66afe90 100644
> --- a/tools/perf/Makefile.config
> +++ b/tools/perf/Makefile.config
> @@ -1280,7 +1280,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 8fe603aa9773..1768948d17b5 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.
> #
> @@ -483,11 +482,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
> @@ -892,14 +886,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 565ee8d55f80..b6691ebb1b4e 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];
> @@ -2654,8 +2796,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);
> @@ -2690,36 +2830,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)
> @@ -2794,20 +2909,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);
> @@ -3119,9 +3221,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;
>
> @@ -3129,18 +3228,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,
> @@ -3153,12 +3240,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;
> }
>
> @@ -3301,10 +3387,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)
> @@ -3341,96 +3426,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;
> }
> @@ -3618,7 +3655,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"
>
> @@ -3626,7 +3662,6 @@ struct script_desc {
> struct list_head node;
> char *name;
> char *half_liner;
> - char *args;
> };
>
> static LIST_HEAD(script_descs);
> @@ -3641,16 +3676,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);
> }
>
> @@ -3698,15 +3733,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++;
> @@ -3719,14 +3804,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!
> }
> }
>
> @@ -3757,23 +3845,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) {
> @@ -3785,30 +3871,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 : "");
> }
>
> @@ -3844,94 +3926,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;
> @@ -4055,6 +4049,14 @@ static int perf_script__process_auxtrace_info(const struct perf_tool *tool,
> return ret;
> }
>
> +static const char *script_itrace_opts;
> +
> +static int parse_script_itrace(const struct option *opt, const char *str, int unset)
> +{
> + script_itrace_opts = unset ? "" : (str && *str ? str : "cepwx");
> + return itrace_parse_synth_opts(opt, str, unset);
> +}
> +
> static int parse_insn_trace(const struct option *opt __maybe_unused,
> const char *str, int unset __maybe_unused)
> {
> @@ -4074,6 +4076,7 @@ static int parse_insn_trace(const struct option *opt __maybe_unused,
> if (ret < 0)
> return ret;
>
> + script_itrace_opts = "i0nse";
> itrace_parse_synth_opts(opt, "i0nse", 0);
> symbol_conf.nanosecs = true;
> return 0;
> @@ -4095,6 +4098,7 @@ static int parse_call_trace(const struct option *opt __maybe_unused,
> int unset __maybe_unused)
> {
> parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);
> + script_itrace_opts = "cewp";
> itrace_parse_synth_opts(opt, "cewp", 0);
> symbol_conf.nanosecs = true;
> symbol_conf.pad_output_len_dso = 50;
> @@ -4106,27 +4110,102 @@ static int parse_callret_trace(const struct option *opt __maybe_unused,
> int unset __maybe_unused)
> {
> parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0);
> + script_itrace_opts = "crewp";
> itrace_parse_synth_opts(opt, "crewp", 0);
> symbol_conf.nanosecs = true;
> 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;
> @@ -4147,11 +4226,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),
> @@ -4180,8 +4258,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...]",
> @@ -4244,7 +4320,7 @@ int cmd_script(int argc, const char **argv)
> "Use 9 decimal places when displaying time"),
> OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
> "Instruction Tracing options\n" ITRACE_HELP,
> - itrace_parse_synth_opts),
> + parse_script_itrace),
> OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
> "Show full source file name path for source lines"),
> OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
> @@ -4278,22 +4354,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 ||
> @@ -4316,22 +4386,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. "
> @@ -4346,149 +4400,194 @@ 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);
> - }
> -
> - dup2(live_pipe[0], 0);
> - close(live_pipe[1]);
> -
> - __argv = calloc(argc + 4, sizeof(const char *));
> - if (!__argv) {
> - pr_err("malloc failed\n");
> - err = -ENOMEM;
> - goto out;
> - }
> + 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);
> + if (script_itrace_opts)
> + setenv("PERF_ITRACE", script_itrace_opts, 1);
> +
> + execvp(__argv[0], (char **)__argv);
> + {
> + int err_code = errno;
> +
> + pr_err("failed to execute script '%s': %s\n",
> + script_name, strerror(err_code));
> + _exit(err_code);
> + }
> + } else { /* parent */
> + siginfo_t info;
> + int status = 0;
>
> - 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;
> + script_child_pid = pid;
> + sigprocmask(SIG_SETMASK, &old_mask, NULL);
> + /*
> + * Wait with WNOWAIT first so the child remains a
> + * zombie (preventing PID reuse by the kernel) until
> + * script_child_pid is cleared and signal handlers are
> + * restored, then reap the zombie with waitpid().
> + */
> + while (waitid(P_PID, pid, &info, WEXITED | WNOWAIT) < 0) {
> + 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);
> + while (waitpid(pid, &status, 0) != pid) {
> + if (errno == EINTR)
> + continue;
> + err = -errno;
> + goto out;
> + }
> + 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) {
> @@ -4580,79 +4679,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;
> @@ -4680,8 +4711,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);
>
> @@ -4696,10 +4725,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 cf9d4b5d3153..7524de522802 100644
> --- a/tools/perf/tests/make
> +++ b/tools/perf/tests/make
> @@ -79,7 +79,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
> @@ -175,7 +174,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 82cdb1762285..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} -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 c6f5cf80b79f..86313c72f53e 100755
> --- a/tools/perf/tests/shell/test_flamegraph_python.sh
> +++ b/tools/perf/tests/shell/test_flamegraph_python.sh
> @@ -66,7 +66,7 @@ test_file_mode() {
> fi
>
> # Run the script in file mode and validate JSON output
> - 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
> else
> @@ -76,7 +76,7 @@ test_file_mode() {
> # Run the script in pipe ('-') mode and validate JSON output
> rm -f "${temp_json}"
> if ! 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
> @@ -84,7 +84,7 @@ test_file_mode() {
> 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
> @@ -105,7 +105,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 afcf98dc5006..512f2ca0cd1a 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 1c342fce36bb..fa3824cf39fa 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;
> @@ -80,70 +74,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.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-09-26 19:17 UTC|newest]
Thread overview: 216+ 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:20 ` [PATCH v1 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-20 5:20 ` [PATCH v1 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-20 5:20 ` [PATCH v1 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-20 5:20 ` [PATCH v1 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-20 5:20 ` [PATCH v1 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-20 5:20 ` [PATCH v1 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-20 5:21 ` [PATCH v1 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
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:21 ` [PATCH v1 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-20 5:21 ` [PATCH v1 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
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:21 ` [PATCH v1 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
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:21 ` [PATCH v1 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-20 5:21 ` [PATCH v1 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-20 5:21 ` [PATCH v1 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 20/49] perf python: Port gecko " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 26/49] perf python: Port sctop " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 29/49] perf python: Port rwtop " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-20 5:21 ` [PATCH v1 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
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:21 ` [PATCH v1 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-20 5:21 ` [PATCH v1 43/49] perf python: Port export-to-postgresql " Ian Rogers
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: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:21 ` [PATCH v1 48/49] perf script: Support standalone scripts and remove embedded scripting Ian Rogers
2026-09-20 5:21 ` [PATCH v1 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
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:06 ` [PATCH v2 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-21 5:06 ` [PATCH v2 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-21 5:06 ` [PATCH v2 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-21 5:06 ` [PATCH v2 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-21 5:06 ` [PATCH v2 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-21 5:06 ` [PATCH v2 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-21 5:06 ` [PATCH v2 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
2026-09-21 5:06 ` [PATCH v2 09/49] perf python: Add Intel PT call_return and itrace capability Ian Rogers
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:06 ` [PATCH v2 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
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:06 ` [PATCH v2 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
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:06 ` [PATCH v2 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-21 5:06 ` [PATCH v2 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-21 5:06 ` [PATCH v2 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 20/49] perf python: Port gecko " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 26/49] perf python: Port sctop " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 29/49] perf python: Port rwtop " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-21 5:06 ` [PATCH v2 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
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:06 ` [PATCH v2 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
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:07 ` [PATCH v2 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-21 5:07 ` [PATCH v2 43/49] perf python: Port export-to-postgresql " Ian Rogers
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: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:07 ` [PATCH v2 48/49] perf script: Support standalone scripts and remove embedded scripting Ian Rogers
2026-09-21 5:07 ` [PATCH v2 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
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:11 ` [PATCH v3 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-23 18:11 ` [PATCH v3 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-23 18:11 ` [PATCH v3 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-23 18:11 ` [PATCH v3 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-23 18:11 ` [PATCH v3 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-23 18:11 ` [PATCH v3 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-23 18:11 ` [PATCH v3 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
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:11 ` [PATCH v3 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-23 18:11 ` [PATCH v3 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
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:11 ` [PATCH v3 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
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:11 ` [PATCH v3 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-23 18:11 ` [PATCH v3 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-23 18:11 ` [PATCH v3 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 20/49] perf python: Port gecko " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 26/49] perf python: Port sctop " 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:11 ` [PATCH v3 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 29/49] perf python: Port rwtop " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-23 18:11 ` [PATCH v3 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-23 18:12 ` [PATCH v3 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-23 18:12 ` [PATCH v3 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-23 18:12 ` [PATCH v3 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-23 18:12 ` [PATCH v3 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
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:12 ` [PATCH v3 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-23 18:12 ` [PATCH v3 43/49] perf python: Port export-to-postgresql " Ian Rogers
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: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:12 ` [PATCH v3 48/49] perf script: Support standalone scripts and remove embedded scripting Ian Rogers
2026-09-23 18:12 ` [PATCH v3 49/49] perf Documentation: Update for standalone Python scripts Ian Rogers
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:19 ` [PATCH v4 02/49] perf python: Update callchain stubs and session thread lookup Ian Rogers
2026-09-26 6:19 ` [PATCH v4 03/49] perf python: Clean up pylint warnings in ilist.py Ian Rogers
2026-09-26 6:19 ` [PATCH v4 04/49] perf python: Clean up pylint warnings in treport.py Ian Rogers
2026-09-26 6:19 ` [PATCH v4 05/49] perf python: Clean up pylint warnings in tracepoint.py Ian Rogers
2026-09-26 6:19 ` [PATCH v4 06/49] perf python: Clean up pylint warnings in twatch.py Ian Rogers
2026-09-26 6:19 ` [PATCH v4 07/49] perf python: Improve perf script -l descriptions Ian Rogers
2026-09-26 6:19 ` [PATCH v4 08/49] perf python: Expose addr location, transaction, and context_switch Ian Rogers
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:19 ` [PATCH v4 10/49] perf python: Allow KeyboardInterrupt to propagate in LiveSession Ian Rogers
2026-09-26 6:19 ` [PATCH v4 11/49] perf pmu-events: Clean up mypy and pylint issues Ian Rogers
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:19 ` [PATCH v4 13/49] perf build: Make mypy build test opt-out (NO_MYPY=1) Ian Rogers
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:19 ` [PATCH v4 15/49] perf Makefile: Install standalone Python scripts during transition Ian Rogers
2026-09-26 6:19 ` [PATCH v4 16/49] perf python: Port stat-cpi to perf module Ian Rogers
2026-09-26 6:19 ` [PATCH v4 17/49] perf python: Port mem-phys-addr " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 18/49] perf python: Port stackcollapse " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 19/49] perf python: Port flamegraph " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 20/49] perf python: Port gecko " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 21/49] perf python: Port event_analyzing_sample " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 22/49] perf python: Port syscall-counts " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 23/49] perf python: Port syscall-counts-by-pid " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 24/49] perf python: Port failed-syscalls-by-pid " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 25/49] perf python: Port failed-syscalls from Perl " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 26/49] perf python: Port sctop " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 27/49] perf python: Port rw-by-file from Perl " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 28/49] perf python: Port rw-by-pid " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 29/49] perf python: Port rwtop " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 30/49] perf python: Port futex-contention " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 31/49] perf python: Port task-analyzer " Ian Rogers
2026-09-26 6:19 ` [PATCH v4 32/49] perf python: Port sched-migration and SchedGui " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 33/49] perf python: Port wakeup-latency from Perl " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 34/49] perf python: Port compaction-times " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 35/49] perf python: Port net_dropmonitor " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 36/49] perf python: Port netdev-times " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 37/49] perf python: Port check-perf-trace " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 38/49] perf python: Port arm-cs-trace-disasm " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 39/49] perf python: Port powerpc-hcalls " Ian Rogers
2026-09-26 6:20 ` [PATCH v4 40/49] perf python: Port intel-pt-events and libxed " Ian Rogers
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:20 ` [PATCH v4 42/49] perf python: Port export-to-sqlite to perf module Ian Rogers
2026-09-26 6:20 ` [PATCH v4 43/49] perf python: Port export-to-postgresql " Ian Rogers
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: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 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 19:17 ` Arnaldo Carvalho de Melo [this message]
2026-09-26 6:20 ` [PATCH v4 49/49] perf Documentation: Update for standalone Python scripts 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=argaNT7NdOd06YdU@x2 \
--to=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alice.mei.rogers@gmail.com \
--cc=dapeng1.mi@linux.intel.com \
--cc=irogers@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®