xref: /linux/tools/perf/tests/shell/jitdump-python.sh (revision 9e906a9dead17d81d6c2687f65e159231d0e3286)
1*c9cd0c7eSNamhyung Kim#!/bin/bash
2*c9cd0c7eSNamhyung Kim# python profiling with jitdump
3*c9cd0c7eSNamhyung Kim# SPDX-License-Identifier: GPL-2.0
4*c9cd0c7eSNamhyung Kim
5*c9cd0c7eSNamhyung KimSHELLDIR=$(dirname $0)
6*c9cd0c7eSNamhyung Kim# shellcheck source=lib/setup_python.sh
7*c9cd0c7eSNamhyung Kim. "${SHELLDIR}"/lib/setup_python.sh
8*c9cd0c7eSNamhyung Kim
9*c9cd0c7eSNamhyung KimOUTPUT=$(${PYTHON} -Xperf_jit -c 'import os, sys; print(os.getpid(), sys.is_stack_trampoline_active())' 2> /dev/null)
10*c9cd0c7eSNamhyung KimPID=${OUTPUT% *}
11*c9cd0c7eSNamhyung KimHAS_PERF_JIT=${OUTPUT#* }
12*c9cd0c7eSNamhyung Kim
13*c9cd0c7eSNamhyung Kimrm -f /tmp/jit-${PID}.dump 2> /dev/null
14*c9cd0c7eSNamhyung Kimif [ "${HAS_PERF_JIT}" != "True" ]; then
15*c9cd0c7eSNamhyung Kim    echo "SKIP: python JIT dump is not available"
16*c9cd0c7eSNamhyung Kim    exit 2
17*c9cd0c7eSNamhyung Kimfi
18*c9cd0c7eSNamhyung Kim
19*c9cd0c7eSNamhyung KimPERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXXX)
20*c9cd0c7eSNamhyung Kim
21*c9cd0c7eSNamhyung Kimcleanup() {
22*c9cd0c7eSNamhyung Kim    echo "Cleaning up files..."
23*c9cd0c7eSNamhyung Kim    rm -f ${PERF_DATA} ${PERF_DATA}.jit /tmp/jit-${PID}.dump /tmp/jitted-${PID}-*.so 2> /dev/null
24*c9cd0c7eSNamhyung Kim
25*c9cd0c7eSNamhyung Kim    trap - EXIT TERM INT
26*c9cd0c7eSNamhyung Kim}
27*c9cd0c7eSNamhyung Kim
28*c9cd0c7eSNamhyung Kimtrap_cleanup() {
29*c9cd0c7eSNamhyung Kim    echo "Unexpected termination"
30*c9cd0c7eSNamhyung Kim    cleanup
31*c9cd0c7eSNamhyung Kim    exit 1
32*c9cd0c7eSNamhyung Kim}
33*c9cd0c7eSNamhyung Kim
34*c9cd0c7eSNamhyung Kimtrap trap_cleanup EXIT TERM INT
35*c9cd0c7eSNamhyung Kim
36*c9cd0c7eSNamhyung Kimecho "Run python with -Xperf_jit"
37*c9cd0c7eSNamhyung Kimcat <<EOF | perf record -k 1 -g --call-graph dwarf -o "${PERF_DATA}" \
38*c9cd0c7eSNamhyung Kim		 -- ${PYTHON} -Xperf_jit
39*c9cd0c7eSNamhyung Kimdef foo(n):
40*c9cd0c7eSNamhyung Kim    result = 0
41*c9cd0c7eSNamhyung Kim    for _ in range(n):
42*c9cd0c7eSNamhyung Kim        result += 1
43*c9cd0c7eSNamhyung Kim    return result
44*c9cd0c7eSNamhyung Kim
45*c9cd0c7eSNamhyung Kimdef bar(n):
46*c9cd0c7eSNamhyung Kim    foo(n)
47*c9cd0c7eSNamhyung Kim
48*c9cd0c7eSNamhyung Kimdef baz(n):
49*c9cd0c7eSNamhyung Kim    bar(n)
50*c9cd0c7eSNamhyung Kim
51*c9cd0c7eSNamhyung Kimif __name__ == "__main__":
52*c9cd0c7eSNamhyung Kim    baz(1000000)
53*c9cd0c7eSNamhyung KimEOF
54*c9cd0c7eSNamhyung Kim
55*c9cd0c7eSNamhyung Kim# extract PID of the target process from the data
56*c9cd0c7eSNamhyung Kim_PID=$(perf report -i "${PERF_DATA}" -F pid -q -g none | cut -d: -f1 -s)
57*c9cd0c7eSNamhyung KimPID=$(echo -n $_PID)  # remove newlines
58*c9cd0c7eSNamhyung Kim
59*c9cd0c7eSNamhyung Kimecho "Generate JIT-ed DSOs using perf inject"
60*c9cd0c7eSNamhyung KimDEBUGINFOD_URLS='' perf inject -i "${PERF_DATA}" -j -o "${PERF_DATA}.jit"
61*c9cd0c7eSNamhyung Kim
62*c9cd0c7eSNamhyung Kimecho "Add JIT-ed DSOs to the build-ID cache"
63*c9cd0c7eSNamhyung Kimfor F in /tmp/jitted-${PID}-*.so; do
64*c9cd0c7eSNamhyung Kim  perf buildid-cache -a "${F}"
65*c9cd0c7eSNamhyung Kimdone
66*c9cd0c7eSNamhyung Kim
67*c9cd0c7eSNamhyung Kimecho "Check the symbol containing the function/module name"
68*c9cd0c7eSNamhyung KimNUM=$(perf report -i "${PERF_DATA}.jit" -s sym | grep -cE 'py::(foo|bar|baz):<stdin>')
69*c9cd0c7eSNamhyung Kim
70*c9cd0c7eSNamhyung Kimecho "Found ${NUM} matching lines"
71*c9cd0c7eSNamhyung Kim
72*c9cd0c7eSNamhyung Kimecho "Remove JIT-ed DSOs from the build-ID cache"
73*c9cd0c7eSNamhyung Kimfor F in /tmp/jitted-${PID}-*.so; do
74*c9cd0c7eSNamhyung Kim  perf buildid-cache -r "${F}"
75*c9cd0c7eSNamhyung Kimdone
76*c9cd0c7eSNamhyung Kim
77*c9cd0c7eSNamhyung Kimcleanup
78*c9cd0c7eSNamhyung Kim
79*c9cd0c7eSNamhyung Kimif [ "${NUM}" -eq 0 ]; then
80*c9cd0c7eSNamhyung Kim    exit 1
81*c9cd0c7eSNamhyung Kimfi
82