diff options
Diffstat (limited to 'tools/perf/scripts')
| -rwxr-xr-x | tools/perf/scripts/install-build-deps.sh | 603 | ||||
| -rwxr-xr-x | tools/perf/scripts/python/arm-cs-trace-disasm.py | 9 | ||||
| -rw-r--r-- | tools/perf/scripts/python/powerpc-hcalls.py | 137 |
3 files changed, 743 insertions, 6 deletions
diff --git a/tools/perf/scripts/install-build-deps.sh b/tools/perf/scripts/install-build-deps.sh new file mode 100755 index 000000000000..d003e7fab2be --- /dev/null +++ b/tools/perf/scripts/install-build-deps.sh @@ -0,0 +1,603 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# No 'set -e': the script uses explicit checks for its error paths, and +# is also run via '$(SHELL) .../install-build-deps.sh' from the make +# target in tools/perf/Makefile.perf, where a shebang option would be +# ignored anyway, so direct and make-driven runs behave the same. +# +# Install the development packages needed to build tools/perf. +# +# The package set is derived from the feature tests in tools/build/feature/: +# each feature test that perf may compile is mapped to the devel package +# that provides the headers/libraries it checks, so that a subsequent +# 'make -C tools/perf' build enables the corresponding perf features. +# +# Currently supported distros, each validated in a fresh container: +# +# - Fedora, on dnf, validated on Fedora 44, in a toolbx container: +# +# toolbox create fedora:44 +# toolbox enter fedora:44 +# +# - Ubuntu, on apt-get, validated on Ubuntu 26.04, in a distrobox +# container: +# +# distrobox create --image ubuntu:26.04 +# distrobox enter ubuntu-26-04 +# +# The apt-get install runs with a noninteractive debconf frontend: +# default-jdk, needed by the jvmti feature tests, pulls in tzdata, +# which prompts for the timezone on a terminal and would block the +# install, e.g. in a container shared with an interactive session. +# +# - Debian, on apt-get, reusing the Ubuntu mapping, validated on +# Debian 13 (trixie), in a distrobox container: +# +# distrobox create --image debian:trixie +# distrobox enter debian-trixie +# +# - RHEL and its variants (RHEL, CentOS Stream, Rocky Linux, AlmaLinux, +# Oracle Linux), on dnf (RHEL 8 and later), validated on CentOS +# Stream 10, in a distrobox container: +# +# distrobox create --image quay.io/centos/centos:stream10 +# distrobox enter centos-stream10 +# +# The RHEL family reuses most Fedora package names, with these +# differences, handled by probing the enabled repos: +# +# - zlib.h comes from zlib-ng-compat-devel on the RHEL 10 family, +# zlib-devel on RHEL 9 and earlier; +# - the JDK devel package is versioned, there is no +# java-latest-openjdk-devel: java-21-openjdk-devel on the RHEL +# 10 family, java-17-openjdk-devel on RHEL 9, java-11-openjdk- +# devel on RHEL 8; +# - libbpf-devel and capstone-devel are in the CRB repo on RHEL +# and CentOS Stream 10 ('dnf config-manager --set-enabled crb') +# and in EPEL on RHEL 9 and earlier; +# - libbabeltrace2-devel is not packaged on the RHEL 10 family. +# +# On the RHEL family, packages not available on the enabled repos +# are skipped and listed at the end of the run, so that a distro +# with CRB/EPEL enabled gets the full set, and a distro without +# them still installs what it can. +# +# Running inside a container keeps the host system unmodified. +# +# Usage: install-build-deps.sh [OPTIONS] +# +# Options: +# --list list the packages that would be installed, then exit +# --dry-run show the install command that would be run, without +# running it +# --distro ID force a distro: fedora, rhel, ubuntu, debian +# (default: auto-detect) +# -h, --help print this help message +# +# Requires root (or passwordless sudo) to actually install packages. + +set -u + +DISTRO="" + +help() { + cat <<EOF +Usage: $(basename "$0") [--list] [--dry-run] [--distro ID] [-h|--help] + +Install the development packages needed to build tools/perf. + +The package set is derived from the feature tests in tools/build/feature/, +mapping each one with an external dependency to the devel package providing +it, so the corresponding feature gets enabled on a build. + +Options: + --list list the packages that would be installed, then exit + --dry-run show the install command that would be run, without running it + --distro ID force a distro: fedora, rhel, ubuntu, debian + -h, --help print this help message + +Distros supported: Fedora (dnf), validated in a toolbx container on +Fedora 44, Ubuntu (apt-get), validated in a distrobox container on +Ubuntu 26.04, Debian (apt-get), reusing the Ubuntu mapping, validated +in a distrobox container on Debian 13 (trixie), and the RHEL family +(dnf, RHEL 8 and later), validated on CentOS Stream 10 in a distrobox +container. On the RHEL family, packages not available on the enabled +repos are skipped and listed at the end; some there, e.g. +libbpf-devel and capstone-devel, come from the CRB repo on RHEL and +CentOS Stream 10 ('dnf config-manager --set-enabled crb') and from +EPEL on RHEL 9 and earlier. +EOF + exit 0 +} + +# --------------------------------------------------------------------- +# Return the Fedora package(s) providing the devel requirements of a +# feature test in tools/build/feature/. Multiple packages are separated +# by spaces; an empty result means the test has no external devel +# dependency (pure toolchain/glibc, or no equivalent Fedora package). +# +# The mapping was built by checking, for each feature test, which Fedora +# devel package provides the headers the test compiles against. +# --------------------------------------------------------------------- +fedora_pkg_for() { + local feat="$1" + case "$feat" in + libelf|libelf-getphdrnum|libelf-gelf_getnote|libelf-getshdrstrndx) + echo "elfutils-libelf-devel" + ;; + libelf-zstd) + echo "elfutils-libelf-devel libzstd-devel" + ;; + libdw) + echo "elfutils-devel" + ;; + # test-libdebuginfod.c includes <elfutils/debuginfod.h>, which is + # provided by elfutils-debuginfod-client-devel, not elfutils-devel. + libdebuginfod) + echo "elfutils-debuginfod-client-devel" + ;; + libnuma|numa_num_possible_cpus) + echo "numactl-devel" + ;; + libzstd) + echo "libzstd-devel" + ;; + zlib) + echo "zlib-devel" + ;; + lzma) + echo "xz-devel" + ;; + libslang) + echo "slang-devel" + ;; + libcapstone) + echo "capstone-devel" + ;; + libpython) + echo "python3-devel" + ;; + libtraceevent) + echo "libtraceevent-devel" + ;; + cxa-demangle) + echo "libstdc++-devel" + ;; + libbpf) + echo "libbpf-devel" + ;; + babeltrace2-ctf-writer) + echo "libbabeltrace2-devel" + ;; + libopenssl) + echo "openssl-devel" + ;; + libpfm4) + echo "libpfm-devel" + ;; + sdt) + echo "systemtap-sdt-devel" + ;; + clang-bpf-co-re) + echo "clang-devel" + ;; + llvm|llvm-perf) + echo "llvm-devel" + ;; + jvmti|jvmti-cmlr) + echo "java-latest-openjdk-devel" + ;; + esac + # Pure toolchain/libc features (backtrace, eventfd, fortify-source, + # gettid, glibc, hello, reallocarray, pthread-*, stackprotector-all, + # timerfd, scandirat, sched_getcpu, setns, file-handle, + # bionic...) need no external package: their + # requirements are covered by the base packages below. Features that + # perf's own build does not check (libcap, libcheck, libcpupower, + # libtracefs, whose feature tests exist for rtla/bpftool/rv) and the + # opt-in features, which a default build does not enable: the libbfd + # disassembler family (libbfd, libbfd-threadsafe, libbfd-liberty, + # disassembler-*, cplus-demangle), only linked on BUILD_NONDISTRO + # builds and deprecated in favor of capstone, GTK2, LIBPERL and + # LIBUNWIND support (ifdef GTK2 / ifdef LIBPERL / LIBUNWIND=1), + # and CoreSight (ifdef CORESIGHT), are deliberately not mapped. + # libaio is not mapped either: its + # test uses the POSIX AIO API (aio.h, aio_*, -lrt), provided by + # glibc headers (pulled in by the libc headers package) in the + # base set, not the native libaio.h/io_submit API that + # libaio-devel provides. +} + +# --------------------------------------------------------------------- +# Check whether the first argument is provided by the enabled repos, or +# is already installed, returning 0 if so and printing nothing. +# +# dnf repoquery exits 0 even when the pattern does not match anything, +# so availability is judged by the output being non-empty, not by the +# exit code. +# --------------------------------------------------------------------- +pkg_available() { + local p out + for p in "$@"; do + out=$(dnf repoquery --quiet --available "$p" 2>/dev/null) + [ -n "$out" ] || out=$(dnf repoquery --quiet --installed "$p" 2>/dev/null) + [ -n "$out" ] && return 0 + done + return 1 +} + +# --------------------------------------------------------------------- +# Return the first of its arguments that pkg_available() accepts. +# --------------------------------------------------------------------- +pick_available() { + local p + for p in "$@"; do + if pkg_available "$p"; then + echo "$p" + return 0 + fi + done + return 1 +} + +# --------------------------------------------------------------------- +# Return the RHEL-family package(s) providing the devel requirements of +# a feature test. This family reuses the Fedora mapping, whose names +# apply to it as well, except for the features whose Fedora package +# does not exist there, kept in the case below. +# +# Whether the resulting package is actually installable is checked in +# package_set(), as some of these names live in the CRB or EPEL repos, +# which may not be enabled: on the RHEL 10 family libbpf-devel and +# capstone-devel come from CRB, and libbabeltrace2-devel is not +# packaged at all. +# --------------------------------------------------------------------- +rhel_pkg_for() { + local feat="$1" + case "$feat" in + zlib) + # zlib-ng-compat-devel on the RHEL 10 family, zlib-devel on + # RHEL 9 and earlier. If neither is on the enabled repos, + # fall back to the first candidate so that package_set() + # reports it as missing instead of silently dropping the + # feature from the end-of-run note. + pick_available zlib-devel zlib-ng-compat-devel || echo "zlib-devel" + ;; + jvmti|jvmti-cmlr) + # No java-latest-openjdk-devel on the RHEL family: the JDK + # devel package is versioned per release. + pick_available java-latest-openjdk-devel java-21-openjdk-devel java-17-openjdk-devel java-11-openjdk-devel || echo "java-latest-openjdk-devel" + ;; + *) + fedora_pkg_for "$feat" + ;; + esac +} + +# --------------------------------------------------------------------- +# Return the Debian/Ubuntu package(s) providing the devel requirements +# of a feature test in tools/build/feature/. This mapping is shared by +# Debian and Ubuntu, whose package names for these devel packages match, +# and is validated on Ubuntu 26.04 and Debian 13 (trixie). +# --------------------------------------------------------------------- +debian_pkg_for() { + local feat="$1" + case "$feat" in + libelf|libelf-getphdrnum|libelf-gelf_getnote|libelf-getshdrstrndx) + echo "libelf-dev" + ;; + libelf-zstd) + echo "libelf-dev libzstd-dev" + ;; + libdw) + echo "libdw-dev" + ;; + libdebuginfod) + echo "libdebuginfod-dev" + ;; + libnuma|numa_num_possible_cpus) + echo "libnuma-dev" + ;; + libzstd) + echo "libzstd-dev" + ;; + zlib) + echo "zlib1g-dev" + ;; + lzma) + echo "liblzma-dev" + ;; + libslang) + echo "libslang2-dev" + ;; + libcapstone) + echo "libcapstone-dev" + ;; + libpython) + echo "python3-dev" + ;; + libtraceevent) + echo "libtraceevent-dev" + ;; + # The cxa-demangle feature test links against libstdc++ builtin + # demangling, so on Debian-derived distros it is covered by the + # g++ base package below, which pulls in libstdc++-*-dev. + cxa-demangle) + ;; + libbpf) + echo "libbpf-dev" + ;; + babeltrace2-ctf-writer) + echo "libbabeltrace2-dev" + ;; + libopenssl) + echo "libssl-dev" + ;; + libpfm4) + echo "libpfm4-dev" + ;; + sdt) + echo "systemtap-sdt-dev" + ;; + # test-clang-bpf-co-re.c invokes the clang binary (not libclang-cpp), + # so clang suffices; llvm-dev brings llvm-config, needed by the + # llvm/llvm-perf tests below. + clang-bpf-co-re) + echo "clang llvm-dev" + ;; + llvm|llvm-perf) + echo "llvm-dev" + ;; + jvmti|jvmti-cmlr) + echo "default-jdk" + ;; + esac + # Same rationale as in fedora_pkg_for() above for unmapped tests. +} + +# Base packages needed by any perf build, regardless of feature tests: +# compiler, libc headers, flex/bison for the parser, kernel headers +# for UAPI headers with no in-tree copy, e.g. <linux/capability.h>, and +# gcc-c++ (dnf) / g++ (apt) is needed by the C++-based feature tests +# (cxa-demangle, llvm, llvm-perf), compiled with $(CXX), and +# pulls in libstdc++-devel / libstdc++-*-dev. +# python3-setuptools is needed to build the python binding (perf's +# util/setup.py uses it; without it binding is skipped with a warning). +# rust is not a header-based feature test: test-rust.bin just checks +# "$(RUSTC) --version" (tools/build/feature/Makefile), so it is mapped +# here like the other toolchain packages. +fedora_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers python3-setuptools rust" +# pkg-config mirrors the pkgconf-pkg-config package that Fedora +# installs by default, needed by the babeltrace2 feature test and +# libopenssl's pkg-config checks. +debian_base_pkgs="gcc g++ make pkg-config flex bison libc6-dev linux-libc-dev python3-setuptools rustc" +# pkg-config: like Fedora, on pkgconf since Fedora 26 / RHEL 8, with +# 'pkgconfig' live only as a virtual Provides of the pkgconf-pkg-config +# subpackage. List it explicitly because, unlike Fedora, a minimal +# RHEL-family container may not have it preinstalled. +rhel_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers pkgconf-pkg-config python3-setuptools rust" + +# --------------------------------------------------------------------- +# Distro detection +# --------------------------------------------------------------------- +detect_distro() { + if [ -n "$DISTRO" ]; then + echo "$DISTRO" + return + fi + local id + id=$( . /etc/os-release 2>/dev/null && echo "${ID:-}" ) + case "$id" in + fedora) echo "fedora" ;; + rhel|centos|rocky|almalinux|ol) + # All share the Fedora package names (with the exceptions + # handled by rhel_pkg_for()) and dnf. + echo "rhel" ;; + ubuntu) echo "ubuntu" ;; + debian) echo "debian" ;; + *) echo "" ;; + esac +} + +# --------------------------------------------------------------------- +# Feature test enumeration: mirror of the tests checked during a build, +# from the actual test-*.c / test-*.cpp sources in tools/build/feature/. +# --------------------------------------------------------------------- +feature_tests() { + local srcdir="$1" + local f + for f in "$srcdir"/tools/build/feature/test-*.c "$srcdir"/tools/build/feature/test-*.cpp; do + [ -e "$f" ] || continue + basename "$f" | sed -e 's/^test-//' -e 's/\.c$//' -e 's/\.cpp$//' + done +} + +# --------------------------------------------------------------------- +# Assemble the unique package list. Since the full feature set is mapped +# unconditionally, this installs the complete devel environment; installing +# an already-present package is a no-op for both dnf and apt-get, making +# this idempotent. On the RHEL family, packages not available on the +# enabled repos are skipped and echoed on stderr, reported at the end of +# the run by the caller (package_set() runs in a subshell, so a variable +# would not survive it). +# --------------------------------------------------------------------- +package_set() { + local distro="$1" srcdir="$2" + local feat pkg pkgs base_pkgs missing_pkgs="" + case "$distro" in + fedora) pkgs="$fedora_base_pkgs" ;; + rhel) pkgs="$rhel_base_pkgs" ;; + ubuntu|debian) pkgs="$debian_base_pkgs" ;; + esac + + # The base set must be checked against the enabled repos as well: + # e.g. 'rust' is only shipped as the rust-toolset AppStream module + # on RHEL 8 and 9, where dnf would abort the whole transaction + # with "No match for argument: rust" instead of skipping it, so + # unavailable base packages are skipped and noted like the mapped + # ones below. + if [ "$distro" = "rhel" ]; then + base_pkgs="$pkgs" + pkgs="" + for pkg in $base_pkgs; do + if pkg_available "$pkg"; then + pkgs="$pkgs $pkg" + else + missing_pkgs="$missing_pkgs $pkg" + fi + done + fi + + for feat in $(feature_tests "$srcdir"); do + case "$distro" in + fedora) pkg=$(fedora_pkg_for "$feat") ;; + rhel) pkg=$(rhel_pkg_for "$feat") ;; + *) pkg=$(debian_pkg_for "$feat") ;; + esac + # An empty result means the feature test has no external devel + # dependency (see the unmapped list in fedora_pkg_for()), so + # there is nothing to install and nothing to report as missing: + # packages that are genuinely unavailable on the RHEL family + # surface through rhel_pkg_for() falling back to its first + # candidate, so that the pkg_available() check below catches + # them and adds them to missing_pkgs. + [ -n "$pkg" ] || continue + for pkg in $pkg; do + if [ "$distro" = "rhel" ] && ! pkg_available "$pkg"; then + missing_pkgs="$missing_pkgs $pkg" + continue + fi + case " $pkgs " in + *" $pkg "*) ;; + *) pkgs="$pkgs $pkg" ;; + esac + done + done + [ -n "$missing_pkgs" ] && echo "$missing_pkgs" >&2 + echo "$pkgs" +} + +# --------------------------------------------------------------------- +# Report the RHEL-family packages that were skipped because the enabled +# repos do not provide them. +# --------------------------------------------------------------------- +note_missing() { + [ -n "$1" ] || return 0 + echo "Note: these packages are not available on the enabled repos" >&2 + echo "and were not installed, so the features they enable will stay" >&2 + echo "off in a perf build:" >&2 + echo "$1" | tr ' ' '\n' | grep -v '^$' | sort -u | sed 's/^/ /' >&2 + echo >&2 +} + +# --------------------------------------------------------------------- +# The install command proper for each supported package manager, plus +# the command massaged for --dry-run. +# --------------------------------------------------------------------- +install_cmd() { + local distro="$1"; shift + case "$distro" in + fedora|rhel) + echo "dnf install -y $*" + ;; + ubuntu|debian) + # a fresh container has no package index, so update first; run + # with a noninteractive debconf frontend: default-jdk, used by + # the jvmti feature tests, pulls in tzdata, which prompts for + # the timezone on a terminal and would block the install. The + # env var prefix works with the 'sh -c' invocation below, and + # shows up in --dry-run. + echo "DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y $*" + ;; + esac +} + +main() { + local action="install" + # Package accumulation happens in package_set(), which, together + # with the *_pkg_for() helpers, declares the per-feature 'pkg' + # locals; main() holds no per-feature package state, just the + # distro-wide list assembled by package_set(). + local srcdir distro pkgs cmd missing_file missing_pkgs + + while [ $# -gt 0 ]; do + case "$1" in + --list) action="list"; shift ;; + --dry-run) action="dry-run"; shift ;; + --distro) + [ $# -ge 2 ] || { + echo "error: --distro requires an argument (fedora, rhel, ubuntu, debian)" >&2 + exit 1 + } + DISTRO="$2"; shift 2 ;; + -h|--help) help ;; + *) echo "error: unknown argument: $1" >&2; exit 1 ;; + esac + done + + srcdir=$(cd "$(dirname "$0")/../../.." && pwd) + distro=$(detect_distro) + case "$distro" in + fedora|rhel|ubuntu|debian) ;; + *) + echo "error: unsupported distro (got '$distro'); the package mapping is not validated on other distros." >&2 + echo "Supported and validated: Fedora 44 (toolbx container), Ubuntu 26.04 and Debian 13 (distrobox containers), and CentOS Stream 10 (distrobox container)." >&2 + exit 1 + ;; + esac + + # The RHEL family mapping probes the enabled repos with dnf + # repoquery and installs with dnf, so reject the yum-only members of + # the family (RHEL 7 and earlier, e.g. Oracle Linux 7) with a clear + # error instead of silently judging every package as unavailable. + if [ "$distro" = "rhel" ] && ! command -v dnf >/dev/null 2>&1; then + echo "error: dnf not found, the RHEL family package mapping requires dnf (RHEL 8 and later)." >&2 + exit 1 + fi + + missing_file=$(mktemp) || { + echo "error: cannot create a temporary file (mktemp failed)" >&2 + exit 1 + } + # package_set() runs in a subshell, doing dnf repoquery loops that + # may be interrupted: a Ctrl-C during those loops hits these traps, + # turning SIGINT/SIGTERM into an exit that triggers the EXIT trap, + # removing the temp file, so the script terminates instead of + # resuming after the interrupted command, leaving no file behind. + trap 'rm -f "$missing_file"' EXIT + trap 'exit 1' INT TERM + pkgs=$(package_set "$distro" "$srcdir" 2>"$missing_file") + missing_pkgs=$(cat "$missing_file") + rm -f "$missing_file" + trap - EXIT INT TERM + + case "$action" in + list) + echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort + note_missing "$missing_pkgs" + exit 0 + ;; + dry-run) + install_cmd "$distro" $pkgs + note_missing "$missing_pkgs" + exit 0 + ;; + esac + + echo "The following packages will be installed to enable perf features:" + echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort | sed 's/^/ /' + echo + cmd=$(install_cmd "$distro" $pkgs) + if [ "$(id -u)" -eq 0 ]; then + sh -c "$cmd" + else + sudo sh -c "$cmd" + fi || { + echo "error: the install command failed, see the output above" >&2 + exit 1 + } + note_missing "$missing_pkgs" +} + +main "$@" diff --git a/tools/perf/scripts/python/arm-cs-trace-disasm.py b/tools/perf/scripts/python/arm-cs-trace-disasm.py index 8f6fa4a007b4..42579f858684 100755 --- a/tools/perf/scripts/python/arm-cs-trace-disasm.py +++ b/tools/perf/scripts/python/arm-cs-trace-disasm.py @@ -31,18 +31,19 @@ from perf_trace_context import perf_sample_srccode, perf_config_get # # Output disassembly with objdump and auto detect vmlinux # (when running on same machine.): -# perf script -s scripts/python/arm-cs-trace-disasm.py -d +# perf script --itrace=b -s scripts/python/arm-cs-trace-disasm.py \ +# -- -d # # Output disassembly with llvm-objdump: -# perf script -s scripts/python/arm-cs-trace-disasm.py \ +# perf script --itrace=b -s scripts/python/arm-cs-trace-disasm.py \ # -- -d llvm-objdump-11 -k path/to/vmlinux # # Output accurate disassembly by passing kcore to script: -# perf script -s scripts/python/arm-cs-trace-disasm.py \ +# perf script --itrace=b -s scripts/python/arm-cs-trace-disasm.py \ # -- -d -k perf.data/kcore_dir/kcore # # Output only source line and symbols: -# perf script -s scripts/python/arm-cs-trace-disasm.py +# perf script --itrace=b -s scripts/python/arm-cs-trace-disasm.py def default_objdump(): config = perf_config_get("annotate.objdump") diff --git a/tools/perf/scripts/python/powerpc-hcalls.py b/tools/perf/scripts/python/powerpc-hcalls.py index 8b78dc790adb..fedce1b68cad 100644 --- a/tools/perf/scripts/python/powerpc-hcalls.py +++ b/tools/perf/scripts/python/powerpc-hcalls.py @@ -25,6 +25,7 @@ from Util import * # } ... # } output = {} +sort_key = 'count' # d_enter: { # cpu: { @@ -112,15 +113,17 @@ hcall_table = { 420: 'H_CREATE_RPT', 424: 'H_REMOVE_RPT', 428: 'H_REGISTER_RPAGES', - 432: 'H_DISABLE_AND_GETC', + 432: 'H_DISABLE_AND_GET', 436: 'H_ERROR_DATA', 440: 'H_GET_HCA_INFO', 444: 'H_GET_PERF_COUNT', 448: 'H_MANAGE_TRACE', + 456: 'H_GET_CPU_CHARACTERISTICS', 468: 'H_FREE_LOGICAL_LAN_BUFFER', 472: 'H_POLL_PENDING', 484: 'H_QUERY_INT_STATE', 580: 'H_ILLAN_ATTRIBUTES', + 584: 'H_ADD_LOGICAL_LAN_BUFFERS', 592: 'H_MODIFY_HEA_QP', 596: 'H_QUERY_HEA_QP', 600: 'H_QUERY_HEA', @@ -135,11 +138,17 @@ hcall_table = { 644: 'H_ADD_CONN', 648: 'H_DEL_CONN', 664: 'H_JOIN', + 672: 'H_VASI_SIGNAL', 676: 'H_VASI_STATE', + 680: 'H_VIOCTL', 688: 'H_ENABLE_CRQ', 696: 'H_GET_EM_PARMS', 720: 'H_SET_MPP', 724: 'H_GET_MPP', + 732: 'H_REG_SUB_CRQ', + 736: 'H_FREE_SUB_CRQ', + 740: 'H_SEND_SUB_CRQ', + 744: 'H_SEND_SUB_CRQ_INDIRECT', 748: 'H_HOME_NODE_ASSOCIATIVITY', 756: 'H_BEST_ENERGY', 764: 'H_XIRR_X', @@ -147,7 +156,88 @@ hcall_table = { 772: 'H_COP', 788: 'H_GET_MPP_X', 796: 'H_SET_MODE', + 808: 'H_BLOCK_REMOVE', + 856: 'H_CLEAR_HPT', + 864: 'H_REQUEST_VMC', + 876: 'H_RESIZE_HPT_PREPARE', + 880: 'H_RESIZE_HPT_COMMIT', + 892: 'H_REGISTER_PROC_TBL', + 896: 'H_SIGNAL_SYS_RESET', + 904: 'H_ALLOCATE_VAS_WINDOW', + 908: 'H_MODIFY_VAS_WINDOW', + 912: 'H_DEALLOCATE_VAS_WINDOW', + 916: 'H_QUERY_VAS_WINDOW', + 920: 'H_QUERY_VAS_CAPABILITIES', + 924: 'H_QUERY_NX_CAPABILITIES', + 928: 'H_GET_NX_FAULT', + 936: 'H_INT_GET_SOURCE_INFO', + 940: 'H_INT_SET_SOURCE_CONFIG', + 944: 'H_INT_GET_SOURCE_CONFIG', + 948: 'H_INT_GET_QUEUE_INFO', + 952: 'H_INT_SET_QUEUE_CONFIG', + 956: 'H_INT_GET_QUEUE_CONFIG', + 960: 'H_INT_SET_OS_REPORTING_LINE', + 964: 'H_INT_GET_OS_REPORTING_LINE', + 968: 'H_INT_ESB', + 972: 'H_INT_SYNC', + 976: 'H_INT_RESET', + 996: 'H_SCM_READ_METADATA', + 1000: 'H_SCM_WRITE_METADATA', + 1004: 'H_SCM_BIND_MEM', + 1008: 'H_SCM_UNBIND_MEM', + 1012: 'H_SCM_QUERY_BLOCK_MEM_BINDING', + 1016: 'H_SCM_QUERY_LOGICAL_MEM_BINDING', + 1020: 'H_SCM_UNBIND_ALL', + 1024: 'H_SCM_HEALTH', + 1048: 'H_SCM_PERFORMANCE_STATS', + 1052: 'H_PKS_GET_CONFIG', + 1056: 'H_PKS_SET_PASSWORD', + 1060: 'H_PKS_GEN_PASSWORD', + 1068: 'H_PKS_WRITE_OBJECT', + 1072: 'H_PKS_GEN_KEY', + 1076: 'H_PKS_READ_OBJECT', + 1080: 'H_PKS_REMOVE_OBJECT', + 1084: 'H_PKS_CONFIRM_OBJECT_FLUSHED', + 1096: 'H_RPT_INVALIDATE', + 1100: 'H_SCM_FLUSH', + 1104: 'H_GET_ENERGY_SCALE_INFO', + 1108: 'H_PKS_SIGNED_UPDATE', + 1112: 'H_HTM', + 1116: 'H_WATCHDOG', + # Platform specific hcalls used by KVM on PowerVM + 1120: 'H_GUEST_GET_CAPABILITIES', + 1124: 'H_GUEST_SET_CAPABILITIES', + 1136: 'H_GUEST_CREATE', + 1140: 'H_GUEST_CREATE_VCPU', + 1144: 'H_GUEST_GET_STATE', + 1148: 'H_GUEST_SET_STATE', + 1152: 'H_GUEST_RUN_VCPU', + 1156: 'H_GUEST_COPY_MEMORY', + 1160: 'H_GUEST_DELETE', + # Key wrapping hcalls + 1168: 'H_PKS_WRAP_OBJECT', + 1172: 'H_PKS_UNWRAP_OBJECT', + # Platform-specific hcalls used by the Ultravisor + 61184: 'H_SVM_PAGE_IN', + 61188: 'H_SVM_PAGE_OUT', + 61192: 'H_SVM_INIT_START', + 61196: 'H_SVM_INIT_DONE', + 61204: 'H_SVM_INIT_ABORT', + # Platform specific hcalls used by KVM 61440: 'H_RTAS', + # Platform specific hcalls used by QEMU/SLOF + 61441: 'H_LOGICAL_MEMOP', + 61442: 'H_CAS', + 61443: 'H_UPDATE_DT', + # Platform specific hcalls provided by PHYP + 61560: 'H_GET_24X7_CATALOG_PAGE', + 61564: 'H_GET_24X7_DATA', + 61568: 'H_GET_PERF_COUNTER_INFO', + # Platform-specific hcalls used for nested HV KVM + 63488: 'H_SET_PARTITION_TABLE', + 63492: 'H_ENTER_NESTED', + 63496: 'H_TLB_INVALIDATE', + 63500: 'H_COPY_TOFROM_GUEST', } def hcall_table_lookup(opcode): @@ -158,10 +248,53 @@ def hcall_table_lookup(opcode): print_ptrn = '%-28s%10s%10s%10s%10s' +def sort_output(opcode): + stats = output[opcode] + + if sort_key == 'min': + return stats['min'] + if sort_key == 'max': + return stats['max'] + if sort_key == 'avg': + return stats['time'] // stats['cnt'] + + return stats['cnt'] + +def trace_begin(): + global sort_key + + valid_sort_keys = ['count', 'min', 'max', 'avg'] + + i = 1 + while i < len(sys.argv): + arg = sys.argv[i] + + if arg == '-s' or arg == '--sort': + if i + 1 >= len(sys.argv): + print("Error: -s/--sort requires a sort key argument") + sys.exit(1) + sort_key = sys.argv[i + 1] + i += 2 + continue + + if arg.startswith('--sort='): + sort_key = arg.split('=', 1)[1] + i += 1 + continue + + i += 1 + + if sort_key not in valid_sort_keys: + print(f"Error: Invalid sort key '{sort_key}'. Valid options are: {', '.join(valid_sort_keys)}") + sys.exit(1) + + print("SORT KEY =", sort_key) + def trace_end(): print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)')) print('-' * 68) - for opcode in output: + for opcode in sorted(output, key = sort_output, + reverse=True): h_name = hcall_table_lookup(opcode) time = output[opcode]['time'] cnt = output[opcode]['cnt'] |
