From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-dl1-f69.google.com (mail-dl1-f69.google.com [74.125.82.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E707C53A892 for ; Wed, 23 Sep 2026 18:15:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.69 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790187370; cv=none; b=TyV62Ui8cej1Eeu33TAvRUSu39lUBaxDrtAJo3INaAMnNKKrnf3cvD0zK+dkk8Rgv4yOVaVN3hKhrIq2+MjQzRdUuqsydLmcq83JuLy99dBnlezvc5SMbEnIRR5q+51mglWREDv6rNK8qFM9MpAoVzizwgjWppBSlXQELf3JMNM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790187370; c=relaxed/simple; bh=NOH9DXJKe+fIoMuUCl3gXilPtkgTEt7G1QN/niuu2QA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=S7HK6XzpyfBLIMHn0XoqU34/06XgvB7ha7UNy/TWS4hfAKVbf5cx0JPfmooYd959lN2bMy2OEkfz+/Z9d/UpruekhnvbRSW1W+w7d8k3rryKozWD0TYmeZszJ2Q4zT9qvCQDkdj4d9gorQOuwZh+E3iPT7GcG8DjpZqMFCLOKCY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ey1g93qa; arc=none smtp.client-ip=74.125.82.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ey1g93qa" Received: by mail-dl1-f69.google.com with SMTP id a92af1059eb24-1383723dfddso2410454c88.0 for ; Wed, 23 Sep 2026 11:15:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790187344; x=1790792144; darn=vger.kernel.org; h=content-transfer-encoding:content-type:cc:to:from:subject :message-id:references:mime-version:in-reply-to:date:from:to:cc :subject:date:message-id:reply-to:content-type; bh=yw1ygkkf+zQE3hfIAjuen6pqVByC1FNDHLJ+wc1OQZg=; b=Ey1g93qaa/eP00emI718OMHjRlJVHM3t4YAQZFukCUa+VXJzlZYDhoohdlhUfH0GLx 2EPbW3Ufp3WFG/V92hXSrsRvXe+JYG7cQwjdfclgb+PGaDPpdpQSAsg90SVr81L5msV/ 2/sF3u+PwxEVnVw8+RR+pUP7gyg7fTZizrX2iTWjD8ySDDJrbMUIPzlbs05dM1Ri8iSx byzMjFl5NRtaTho0C1FJVD78ijAdw/JFnAd6HnB8vGkjqZrE1xEq6F1luUR9/9FMF0v6 BqbWRhxZQVGDBJARfKHJhd69JY4Rq8EBpjpubxdFiDfPOP12qhM004ochDtZq5qZH1rd A1Ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790187344; x=1790792144; h=content-transfer-encoding:content-type:cc:to:from:subject :message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=yw1ygkkf+zQE3hfIAjuen6pqVByC1FNDHLJ+wc1OQZg=; b=rtsUcFrZx93dIsqoSizaJI0Sq9aFmGMiHp3KKBfa6SP9CjRBwQMg0JPowYfVNjadZ9 vEd07BXQJ0CILB6A/1ke+v+9+/t4zVLXWwxEfGwGex+xkMpPbJcj20nUyvdtmJonDX3k UyA9Y+55QRqUcR1hLsfxXDXG8E2VLsP4BkmDwcur4UEyfKn24bHhFuq8TDM698lylwxr U4MnRwiztaBu9aVEuUrpCooiJK+Dz/1c13BwYbAeH6gRQO5bGp165RanavZjhvzXJH5R uPnkeklZ39nK/OwiGgedF8Ynqa50I8xwJNfjgOkJ+JdaKG4hRUi7kTgdpvrYwHeH8+IU mAjA== X-Forwarded-Encrypted: i=1; AKwUvByGfDXS0oZQycOsk7cVM7FmcCZ0ke1NdiS5pQ4BgovveM48n3akQNtn/PdfwGqmfaMfZkESd2Ro3QNLVx8=@vger.kernel.org X-Gm-Message-State: AFuF++mZuelqAi6VG3BjtjicrJipZrpfYLaqLP3wnM5e34qfjwAfSKWT DbrIsUCBnXIkjnpOlqUmgT2z0771bw+vWFCPNLvs0cP25PrrwRvP56hAThBVS3l2deiBDclK/hC Wzja6+oggaA== X-Received: from dlec3-n2.prod.google.com ([2002:a05:701b:4283:20b0:144:dcec:b12a]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:701b:4251:10b0:138:3613:dc6 with SMTP id a92af1059eb24-144f90a7081mr3632182c88.14.1790187342863; Wed, 23 Sep 2026 11:15:42 -0700 (PDT) Date: Wed, 23 Sep 2026 11:12:11 -0700 In-Reply-To: <20260923181213.3032038-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260923181213.3032038-1-irogers@google.com> X-Mailer: git-send-email 2.56.0.rc1.310.g51773c2048-goog Message-ID: <20260923181213.3032038-49-irogers@google.com> Subject: [PATCH v3 48/49] perf script: Support standalone scripts and remove embedded scripting From: Ian Rogers To: irogers@google.com, acme@kernel.org, alice.mei.rogers@gmail.com, namhyung@kernel.org Cc: adrian.hunter@intel.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 EOF - if ! "$PYTHON" "$script_path" -i "${temp_data}" -f html --template "${tem= p_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=3D1 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 =20 - 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=3D1 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 =20 # Run the script in save-only mode with custom product and category color= s - 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 =20 # 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=3D1 else diff --git a/tools/perf/tests/shell/test_mem_phys_addr_python.sh b/tools/pe= rf/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 =20 # 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=3D1 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 =20 # 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=3D1 else diff --git a/tools/perf/tests/shell/test_netdev_times_python.sh b/tools/per= f/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 =20 # 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=3D1 else diff --git a/tools/perf/tests/shell/test_powerpc_hcalls_python.sh b/tools/p= erf/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 =20 # 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=3D1 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 =20 # 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=3D1 else diff --git a/tools/perf/tests/shell/test_rw_by_pid_python.sh b/tools/perf/t= ests/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 =20 # 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=3D1 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 =20 # 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=3D1 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 =20 # 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_o= ut}"; then echo "sched-migration.py test failed" err=3D1 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 =20 # 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=3D1 elif ! grep -E -q "[0-9]+$" "${temp_out}"; then echo "Failed to find metric data rows in default run" err=3D1 -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=3D1 else diff --git a/tools/perf/tests/shell/test_stackcollapse_python.sh b/tools/pe= rf/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 =20 # 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=3D1 else @@ -61,12 +61,12 @@ else fi =20 # 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_ou= t}" || \ [ ! -s "${temp_out}" ]; then echo "stackcollapse.py options/pipe test failed" err=3D1 -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=3D1 diff --git a/tools/perf/tests/shell/test_stat_cpi_python.sh b/tools/perf/te= sts/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=3D1 =20 # Run live mode for 1 interval in the background, give it a tiny sleep, t= hen 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=3D$! sleep 0.5 kill -INT "$pid" 2>/dev/null || true @@ -96,7 +96,7 @@ test_file_mode() { fi ran=3D1 =20 - out=3D$("$PYTHON" "$script_path" -i "${temp_data}") + out=3D$(perf script stat-cpi -i "${temp_data}") if ! echo "$out" | grep -q "cpi"; then echo "File mode test failed." err=3D1 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; } =20 - 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=3D1 elif ! grep -E -q "^ [a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then @@ -64,7 +64,7 @@ test_file_mode() { fi =20 # 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" > "${tem= p_out}"; then echo "Comm filter test failed." err=3D1 elif ! grep -E -q "^ [a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then @@ -76,7 +76,8 @@ test_file_mode() { =20 # Extract sleep PID from "sleep []" header and test with a numeric P= ID filter argument sleep_pid=3D$(sed -n 's/^sleep \[\([0-9]\+\)\]$/\1/p' "${temp_out}" | hea= d -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=3D1 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/p= erf/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 =20 - 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=3D1 elif ! grep -E -q "^[a-zA-Z0-9_]+ +[0-9]+$" "${temp_out}"; then @@ -65,7 +65,7 @@ test_file_mode() { fi =20 # 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=3D1 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/test= s/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=3D"$tmpdir/csv" csvsummary=3D"$tmpdir/csvsummary" err=3D0 =20 -# Set up perfdir and PERF_EXEC_PATH -if [ "x$PERF_EXEC_PATH" =3D "x" ]; then - perfdir=3D"$(dirname "$0")/../.." - if [ -f "$perfdir/python/task-analyzer.py" ]; then - export PERF_EXEC_PATH=3D"$perfdir" - fi -else - perfdir=3D"$PERF_EXEC_PATH" -fi - # Disable lsan to avoid warnings about python memory leaks. export ASAN_OPTIONS=3Ddetect_leaks=3D0 =20 @@ -81,17 +71,17 @@ prepare_perf_data() { # check standard inkvokation with no arguments test_basic() { out=3D"$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]}" } =20 test_ns_rename(){ out=3D"$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(){ =20 test_ms_filtertasks_highlight(){ out=3D"$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]}" } =20 test_extended_times_timelimit_limittasks() { out=3D"$tmpdir/perf.out" - $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --extended-time= s \ + 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() { =20 test_summary() { out=3D"$tmpdir/perf.out" - $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --summary > "$o= ut" - check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} --s= ummary" + 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]}" } =20 test_summaryextended() { out=3D"$tmpdir/perf.out" - $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --summary-exten= ded > "$out" - check_exec_0 "$PYTHON $perfdir/python/task-analyzer.py -i ${perfdata} --s= ummary-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]}" } =20 test_summaryonly() { out=3D"$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} --s= ummary-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]}" } =20 test_extended_times_summary_ns() { out=3D"$tmpdir/perf.out" - $PYTHON $perfdir/python/task-analyzer.py -i "${perfdata}" --extended-time= s \ + 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() { } =20 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} --c= sv ${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]}" } =20 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]}" } =20 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]}" } =20 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/p= erf/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 =20 # 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=3D1 else @@ -71,7 +71,7 @@ fi =20 # Also test zero-wakeups / unhandled events path to verify division-by-zer= o protection if perf record -e cycles -o "${temp_data}" -- perf test -w noploop >/dev/n= ull 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=3D1 diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scri= pts.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 *v= alue, void *data) return 0; } =20 -/* - * 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 =3D openat(dir_fd, filename, O_RDONLY); - if (fd =3D=3D -1) - return -1; - fp =3D fdopen(fd, "r"); - if (!fp) - return -1; - } - - while (fgets(line, sizeof(line), fp)) { - char *p =3D skip_spaces(line); - - if (*p =3D=3D '#') - continue; - - while (strlen(p)) { - int match, len; - struct evsel *pos; - char evname[128]; - - p =3D strstr(p, "-e"); - if (!p) - break; - - p +=3D 2; - p =3D skip_spaces(p); - len =3D strcspn(p, " \t"); - if (!len) - break; - - snprintf(evname, sizeof(evname), "%.*s", (int)len, p); - - match =3D 0; - evlist__for_each_entry(session->evlist, pos) { - if (evsel__name_is(pos, evname)) { - match =3D 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 *scri= ptname, 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, i= nt 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 =3D { - .path =3D input_name, - .mode =3D PERF_DATA_MODE_READ, - }; - char *temp; int i =3D 0; - const char *exec_path =3D get_argv_exec_path(); - - session =3D 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 =3D open(scripts_path, O_DIRECTORY); - } - if (scripts_dir_fd !=3D -1) { - scripts_dir =3D fdopendir(scripts_dir_fd); - if (scripts_dir) { - while ((lang_dirent =3D readdir(scripts_dir)) !=3D NULL) { - if (lang_dirent->d_type !=3D DT_DIR && - (lang_dirent->d_type =3D=3D 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 =3D openat(scripts_dir_fd, lang_dirent->d_name, - O_DIRECTORY); - if (lang_dir_fd =3D=3D -1) - continue; - lang_dir =3D fdopendir(lang_dir_fd); - if (!lang_dir) { - close(lang_dir_fd); - continue; - } - while ((script_dirent =3D readdir(lang_dir)) !=3D NULL) { - if (script_dirent->d_type =3D=3D DT_DIR) - continue; - if (script_dirent->d_type =3D=3D 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 >=3D num) - break; - scnprintf(scripts_path_array[i], pathlen, - "%s/scripts/%s/%s", exec_path, - lang_dirent->d_name, - script_dirent->d_name); - temp =3D strrchr(script_dirent->d_name, '.'); - namelen =3D temp ? (int)(temp - script_dirent->d_name) - : (int)strlen(script_dirent->d_name); - - if (namelen >=3D SCRIPT_NAMELEN) - namelen =3D 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); - } - } =20 #ifdef HAVE_PYTHON_MODULE_SUPPORT { + int namelen; + struct dirent *script_dirent; + char *temp; + const char *exec_path =3D 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 **sc= ripts_path_array, int num } } #endif - perf_session__delete(session); return i; } =20 diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 3ea888f4210a..1d63751af4f2 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -95,7 +95,6 @@ perf-util-y +=3D tool_pmu.o perf-util-y +=3D tp_pmu.o perf-util-y +=3D svghelper.o perf-util-y +=3D trace-event-info.o -perf-util-y +=3D trace-event-scripting.o perf-util-$(CONFIG_LIBTRACEEVENT) +=3D trace-event.o perf-util-$(CONFIG_LIBTRACEEVENT) +=3D trace-event-parse.o perf-util-$(CONFIG_LIBTRACEEVENT) +=3D trace-event-read.o @@ -236,8 +235,6 @@ endif =20 perf-util-y +=3D data-convert-json.o =20 -perf-util-y +=3D scripting-engines/ - perf-util-$(CONFIG_ZLIB) +=3D zlib.o perf-util-$(CONFIG_LZMA) +=3D lzma.o perf-util-$(CONFIG_ZSTD) +=3D zstd.o diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scri= pting-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) +=3D trace-event-perl.o -endif - -CFLAGS_trace-event-perl.o +=3D $(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-aft= er-statement -Wno-switch-enum -Wno-thread-safety-analysis diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/p= erf/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 interpre= ter. - * - * Copyright (C) 2009 Tom Zanussi - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -/* perl needs the following define, right after including stdbool.h */ -#define HAS_BOOL -#include -#include - -#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 =3D __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 =3D 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 =3D 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 =3D=3D 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 =3D 0; - break; - case TEP_PRINT_FIELD: - free(cur_field_name); - cur_field_name =3D 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, ":") =3D=3D 0) - zero_flag_atom =3D 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 =3D newAV(); - if (!list) - goto exit; - - if (!symbol_conf.use_callchain || !sample->callchain) - goto exit; - - cursor =3D get_tls_callchain_cursor(); - - if (thread__resolve_callchain(al->thread, cursor, - sample, NULL, NULL, scripting_max_stack) !=3D 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 =3D callchain_cursor_current(cursor); - if (!node) - break; - - elem =3D newHV(); - if (!elem) - goto exit; - - if (!hv_stores(elem, "ip", newSVuv(node->ip))) { - hv_undef(elem); - goto exit; - } - - if (node->ms.sym) { - HV *sym =3D 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 =3D node->ms.map; - struct dso *dso =3D map ? map__dso(map) : NULL; - const char *dsoname =3D "[unknown]"; - - if (dso) { - if (symbol_conf.show_kernel_path && dso__long_name(dso)) - dsoname =3D dso__long_name(dso); - else - dsoname =3D 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 =3D 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 =3D sample->cpu; - void *data =3D sample->raw_data; - unsigned long long nsecs =3D sample->time; - const char *comm =3D thread__comm_str(thread); - DECLARE_BITMAP(events_defined, TRACE_EVENT_TYPE_MAX); - struct evsel *evsel =3D sample->evsel; - - bitmap_zero(events_defined, TRACE_EVENT_TYPE_MAX); - dSP; - - if (evsel->core.attr.type !=3D PERF_TYPE_TRACEPOINT) - return; - - event =3D evsel__tp_format(evsel); - if (!event) { - pr_debug("ug! no event found for type %" PRIu64, (u64)evsel->core.attr.c= onfig); - return; - } - - pid =3D 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 =3D nsecs / NSEC_PER_SEC; - ns =3D 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 =3D event->format.fields; field; field =3D field->next) { - if (field->flags & TEP_FIELD_IS_STRING) { - int offset; - if (field->flags & TEP_FIELD_IS_DYNAMIC) { - offset =3D *(int *)(data + field->offset); - offset &=3D 0xffff; - if (tep_field_is_relative(field->flags)) - offset +=3D field->offset + field->size; - } else - offset =3D field->offset; - XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); - } else { /* FIELD_IS_NUMERIC */ - val =3D 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 per= f_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_si= ze))); - 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 **ar= gv, - struct perf_session *session) -{ - const char **command_line; - int i, err =3D 0; - - scripting_context->session =3D session; - - command_line =3D malloc((argc + 2) * sizeof(const char *)); - if (!command_line) - return -ENOMEM; - - command_line[0] =3D ""; - command_line[1] =3D script; - for (i =3D 2; i < argc + 2; i++) - command_line[i] =3D argv[i - 2]; - - my_perl =3D perl_alloc(); - perl_construct(my_perl); - - if (perl_parse(my_perl, xs_init, argc + 2, (char **)command_line, - (char **)NULL)) { - err =3D -1; - goto error; - } - - if (perl_run(my_perl)) { - err =3D -1; - goto error; - } - - if (SvTRUE(ERRSV)) { - err =3D -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 *out= file) -{ - int i, not_first, count, nr_events; - struct tep_event **all_events; - struct tep_event *event =3D NULL; - struct tep_format_field *f; - char fname[PATH_MAX]; - FILE *ofp; - - sprintf(fname, "%s.pl", outfile); - ofp =3D fopen(fname, "w"); - if (ofp =3D=3D 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 =3D 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 =3D tep_get_events_count(pevent); - all_events =3D tep_list_events(pevent, TEP_EVENT_SORT_ID); - - for (i =3D 0; all_events && i < nr_events; i++) { - event =3D 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 =3D 0; - count =3D 0; - - for (f =3D event->format.fields; f; f =3D f->next) { - if (not_first++) - fprintf(ofp, ", "); - if (++count % 5 =3D=3D 0) - fprintf(ofp, "\n\t "); - - fprintf(ofp, "$%s", f->name); - } - fprintf(ofp, ") =3D @_;\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 =3D 0; - count =3D 0; - - for (f =3D event->format.fields; f; f =3D f->next) { - if (not_first++) - fprintf(ofp, ", "); - if (count && count % 4 =3D=3D 0) { - fprintf(ofp, "\".\n\t \""); - } - count++; - - fprintf(ofp, "%s=3D", 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 =3D 0; - count =3D 0; - - for (f =3D event->format.fields; f; f =3D f->next) { - if (not_first++) - fprintf(ofp, ", "); - - if (++count % 5 =3D=3D 0) - fprintf(ofp, "\n\t "); - - if (f->flags & TEP_FIELD_IS_FLAG) { - if ((count - 1) % 5 !=3D 0) { - fprintf(ofp, "\n\t "); - count =3D 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 !=3D 0) { - fprintf(ofp, "\n\t "); - count =3D 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) =3D @_;\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) =3D @_;\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) =3D @_;\n" - "\n" - "\tmy @event\t=3D unpack(\"LSS\", $event);\n" - "\tmy @attr\t=3D unpack(\"LLQQQQQLLQQ\", $attr);\n" - "\tmy @sample\t=3D unpack(\"QLLQQQQQLL\", $sample);\n" - "\tmy @raw_data\t=3D 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 =3D { - .name =3D "Perl", - .dirname =3D "perl", - .start_script =3D perl_start_script, - .flush_script =3D perl_flush_script, - .stop_script =3D perl_stop_script, - .process_event =3D perl_process_event, - .generate_script =3D perl_generate_script, -}; diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-ev= ent-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 #include =20 -static int get_common_field(struct scripting_context *context, - int *offset, int *size, const char *type) -{ - struct tep_handle *pevent =3D context->pevent; - struct tep_event *event; - struct tep_format_field *field; - - if (!*size) { - - event =3D tep_get_first_event(pevent); - if (!event) - return 0; - - field =3D tep_find_common_field(event, type); - if (!field) - return 0; - *offset =3D field->offset; - *size =3D 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 =3D 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 =3D 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 =3D 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/trac= e-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 - */ - -#include -#include -#include -#include -#ifdef HAVE_LIBTRACEEVENT -#include -#endif - -#include "debug.h" -#include "event.h" -#include "trace-event.h" -#include "evsel.h" -#include -#include -#include "util/sample.h" - -unsigned int scripting_max_stack =3D 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 =3D malloc(sizeof(*s) + strlen(spec) + 1); - - if (s !=3D NULL) { - strcpy(s->spec, spec); - s->ops =3D 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) =3D=3D 0) - return s; - return NULL; -} - -static int script_spec_register(const char *spec, struct scripting_ops *op= s) -{ - struct script_spec *s; - - s =3D script_spec__find(spec); - if (s) - return -1; - - s =3D 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 =3D 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 =3D 0; - - list_for_each_entry(s, &script_specs, node) { - ret =3D 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 =3D evsel__tp_format(sample->evsel); - - c->pevent =3D tp_format ? tp_format->tep : NULL; -#else - c->pevent =3D NULL; -#endif - c->event_data =3D sample->raw_data; - c->event =3D event; - c->sample =3D sample; - c->al =3D al; - c->addr_al =3D 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_unus= ed, - 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_unus= ed, - 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 =3D { - .name =3D "Python", - .dirname =3D "python", - .start_script =3D python_start_script_unsupported, - .flush_script =3D flush_script_unsupported, - .stop_script =3D stop_script_unsupported, - .process_event =3D process_event_unsupported, - .generate_script =3D python_generate_script_unsupported, -}; - -static void register_python_scripting(struct scripting_ops *scripting_ops) -{ - if (scripting_context =3D=3D NULL) - scripting_context =3D malloc(sizeof(*scripting_context)); - - if (scripting_context =3D=3D 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 =3D { - .name =3D "Perl", - .dirname =3D "perl", - .start_script =3D perl_start_script_unsupported, - .flush_script =3D flush_script_unsupported, - .stop_script =3D stop_script_unsupported, - .process_event =3D process_event_unsupported, - .generate_script =3D perl_generate_script_unsupported, -}; - -static void register_perl_scripting(struct scripting_ops *scripting_ops) -{ - if (scripting_context =3D=3D NULL) - scripting_context =3D malloc(sizeof(*scripting_context)); - - if (scripting_context =3D=3D 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[] =3D { - {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, "ire= t"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "sysc= all"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sy= sret"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"}, - {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_F= LAG_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[] =3D { - {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 =3D 0, ret, ev_idx =3D 0; - u32 xf =3D flags & PERF_ADDITIONAL_STATE_MASK; - u32 types, events; - char xs[16] =3D { 0 }; - - /* Clear additional state bits */ - flags &=3D ~PERF_ADDITIONAL_STATE_MASK; - - if (flags & PERF_IP_FLAG_TRACE_BEGIN) - prefix =3D "tr strt "; - else if (flags & PERF_IP_FLAG_TRACE_END) - prefix =3D "tr end "; - else - prefix =3D ""; - - ret =3D snprintf(str + pos, size - pos, "%s", prefix); - if (ret < 0) - return ret; - pos +=3D ret; - - flags &=3D ~(PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END); - - types =3D flags & ~PERF_IP_FLAG_BRANCH_EVENT_MASK; - for (i =3D 0; sample_flags[i].name; i++) { - if (sample_flags[i].flags !=3D types) - continue; - - ret =3D snprintf(str + pos, size - pos, "%s", sample_flags[i].name); - if (ret < 0) - return ret; - pos +=3D ret; - break; - } - - events =3D flags & PERF_IP_FLAG_BRANCH_EVENT_MASK; - for (i =3D 0; branch_events[i].name; i++) { - if (!(branch_events[i].flags & events)) - continue; - - ret =3D snprintf(str + pos, size - pos, !ev_idx ? "/%s" : ",%s", - branch_events[i].name); - if (ret < 0) - return ret; - pos +=3D ret; - ev_idx++; - } - - /* Add an end character '/' for events */ - if (ev_idx) { - ret =3D snprintf(str + pos, size - pos, "/"); - if (ret < 0) - return ret; - pos +=3D 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 =3D snprintf(str + pos, size - pos, "%*s", - (int)(SAMPLE_FLAGS_STR_ALIGNED_SIZE - ret), xs); - else - ret =3D 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 =3D PERF_IP_FLAG_CHARS; - const size_t n =3D strlen(PERF_IP_FLAG_CHARS); - size_t i, pos =3D 0; - int ret; - - ret =3D sample_flags_to_name(flags, str, sz); - if (ret > 0) - return ret; - - for (i =3D 0; i < n; i++, flags >>=3D 1) { - if ((flags & 1) && pos < sz) - str[pos++] =3D chars[i]; - } - for (; i < 32; i++, flags >>=3D 1) { - if ((flags & 1) && pos < sz) - str[pos++] =3D '?'; - } - if (pos < sz) - str[pos] =3D 0; - - return pos; -} diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 720121c74f1d..19f22ac1faf3 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -7,15 +7,9 @@ #include #include =20 -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; =20 struct trace_event { struct tep_handle *pevent; @@ -79,70 +73,6 @@ struct tracing_data *tracing_data_get(struct list_head *= pattrs, int fd, bool temp); int tracing_data_put(struct tracing_data *tdata); =20 - -struct addr_location; - -struct perf_session; -struct perf_stat_config; - -struct scripting_ops { - const char *name; - const char *dirname; /* For script path .../scripts//... */ - 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 >=3D MAKE_LIB= TRACEEVENT_VERSION(1, 5, 0) #include =20 --=20 2.56.0.rc1.310.g51773c2048-goog