diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 13:59:43 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 13:59:43 -0800 |
commit | 3a36281a17199737b468befb826d4a23eb774445 (patch) | |
tree | 18bbdfcb0c30215883809f248d0334b7ea84d5ba /tools/perf/tests/shell/daemon.sh | |
parent | 7c70f3a7488d2fa62d32849d138bf2b8420fe788 (diff) | |
parent | 3027ce36ccbae74f2e7c1afbfc3f69fee0c2a996 (diff) | |
download | linux-3a36281a17199737b468befb826d4a23eb774445.tar.gz |
Merge tag 'perf-tools-for-v5.12-2020-02-19' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
Pull perf tool updates from Arnaldo Carvalho de Melo:
"New features:
- Support instruction latency in 'perf report', with both memory
latency (weight) and instruction latency information, users can
locate expensive load instructions and understand time spent in
different stages.
- Extend 'perf c2c' to display the number of loads which were blocked
by data or address conflict.
- Add 'perf stat' support for L2 topdown events in systems such as
Intel's Sapphire rapids server.
- Add support for PERF_SAMPLE_CODE_PAGE_SIZE in various tools, as a
sort key, for instance:
perf report --stdio --sort=comm,symbol,code_page_size
- New 'perf daemon' command to run long running sessions while
providing a way to control the enablement of events without
restarting a traditional 'perf record' session.
- Enable counting events for BPF programs in 'perf stat' just like
for other targets (tid, cgroup, cpu, etc), e.g.:
# perf stat -e ref-cycles,cycles -b 254 -I 1000
1.487903822 115,200 ref-cycles
1.487903822 86,012 cycles
2.489147029 80,560 ref-cycles
2.489147029 73,784 cycles
^C
The example above counts 'cycles' and 'ref-cycles' of BPF program
of id 254. It is similar to bpftool-prog-profile command, but more
flexible.
- Support the new layout for PERF_RECORD_MMAP2 to carry the DSO
build-id using infrastructure generalised from the eBPF subsystem,
removing the need for traversing the perf.data file to collect
build-ids at the end of 'perf record' sessions and helping with
long running sessions where binaries can get replaced in updates,
leading to possible mis-resolution of symbols.
- Support filtering by hex address in 'perf script'.
- Support DSO filter in 'perf script', like in other perf tools.
- Add namespaces support to 'perf inject'
- Add support for SDT (Dtrace Style Markers) events on ARM64.
perf record:
- Fix handling of eventfd() when draining a buffer in 'perf record'.
- Improvements to the generation of metadata events for pre-existing
threads (mmaps, comm, etc), speeding up the work done at the start
of system wide or per CPU 'perf record' sessions.
Hardware tracing:
- Initial support for tracing KVM with Intel PT.
- Intel PT fixes for IPC
- Support Intel PT PSB (synchronization packets) events.
- Automatically group aux-output events to overcome --filter syntax.
- Enable PERF_SAMPLE_DATA_SRC on ARMs SPE.
- Update ARM's CoreSight hardware tracing OpenCSD library to v1.0.0.
perf annotate TUI:
- Fix handling of 'k' ("show line number") hotkey
- Fix jump parsing for C++ code.
perf probe:
- Add protection to avoid endless loop.
cgroups:
- Avoid reading cgroup mountpoint multiple times, caching it.
- Fix handling of cgroup v1/v2 in mixed hierarchy.
Symbol resolving:
- Add OCaml symbol demangling.
- Further fixes for handling PE executables when using perf with Wine
and .exe/.dll files.
- Fix 'perf unwind' DSO handling.
- Resolve symbols against debug file first, to deal with artifacts
related to LTO.
- Fix gap between kernel end and module start on powerpc.
Reporting tools:
- The DSO filter shouldn't show samples in unresolved maps.
- Improve debuginfod support in various tools.
build ids:
- Fix 16-byte build ids in 'perf buildid-cache', add a 'perf test'
entry for that case.
perf test:
- Support for PERF_SAMPLE_WEIGHT_STRUCT.
- Add test case for PERF_SAMPLE_CODE_PAGE_SIZE.
- Shell based tests for 'perf daemon's commands ('start', 'stop,
'reconfig', 'list', etc).
- ARM cs-etm 'perf test' fixes.
- Add parse-metric memory bandwidth testcase.
Compiler related:
- Fix 'perf probe' kretprobe issue caused by gcc 11 bug when used
with -fpatchable-function-entry.
- Fix ARM64 build with gcc 11's -Wformat-overflow.
- Fix unaligned access in sample parsing test.
- Fix printf conversion specifier for IP addresses on arm64, s390 and
powerpc.
Arch specific:
- Support exposing Performance Monitor Counter SPRs as part of
extended regs on powerpc.
- Add JSON 'perf stat' metrics for ARM64's imx8mp, imx8mq and imx8mn
DDR, fix imx8mm ones.
- Fix common and uarch events for ARM64's A76 and Ampere eMag"
* tag 'perf-tools-for-v5.12-2020-02-19' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: (148 commits)
perf buildid-cache: Don't skip 16-byte build-ids
perf buildid-cache: Add test for 16-byte build-id
perf symbol: Remove redundant libbfd checks
perf test: Output the sub testing result in cs-etm
perf test: Suppress logs in cs-etm testing
perf tools: Fix arm64 build error with gcc-11
perf intel-pt: Add documentation for tracing virtual machines
perf intel-pt: Split VM-Entry and VM-Exit branches
perf intel-pt: Adjust sample flags for VM-Exit
perf intel-pt: Allow for a guest kernel address filter
perf intel-pt: Support decoding of guest kernel
perf machine: Factor out machine__idle_thread()
perf machine: Factor out machines__find_guest()
perf intel-pt: Amend decoder to track the NR flag
perf intel-pt: Retain the last PIP packet payload as is
perf intel_pt: Add vmlaunch and vmresume as branches
perf script: Add branch types for VM-Entry and VM-Exit
perf auxtrace: Automatically group aux-output events
perf test: Fix unaligned access in sample parsing test
perf tools: Support arch specific PERF_SAMPLE_WEIGHT_STRUCT processing
...
Diffstat (limited to 'tools/perf/tests/shell/daemon.sh')
-rwxr-xr-x | tools/perf/tests/shell/daemon.sh | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/tools/perf/tests/shell/daemon.sh b/tools/perf/tests/shell/daemon.sh new file mode 100755 index 000000000000..e5b824dd08d9 --- /dev/null +++ b/tools/perf/tests/shell/daemon.sh @@ -0,0 +1,475 @@ +#!/bin/sh +# daemon operations +# SPDX-License-Identifier: GPL-2.0 + +check_line_first() +{ + local line=$1 + local name=$2 + local base=$3 + local output=$4 + local lock=$5 + local up=$6 + + local line_name=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $2 }'` + local line_base=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $3 }'` + local line_output=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $4 }'` + local line_lock=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $5 }'` + local line_up=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $6 }'` + + if [ "${name}" != "${line_name}" ]; then + echo "FAILED: wrong name" + error=1 + fi + + if [ "${base}" != "${line_base}" ]; then + echo "FAILED: wrong base" + error=1 + fi + + if [ "${output}" != "${line_output}" ]; then + echo "FAILED: wrong output" + error=1 + fi + + if [ "${lock}" != "${line_lock}" ]; then + echo "FAILED: wrong lock" + error=1 + fi + + if [ "${up}" != "${line_up}" ]; then + echo "FAILED: wrong up" + error=1 + fi +} + +check_line_other() +{ + local line=$1 + local name=$2 + local run=$3 + local base=$4 + local output=$5 + local control=$6 + local ack=$7 + local up=$8 + + local line_name=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $2 }'` + local line_run=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $3 }'` + local line_base=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $4 }'` + local line_output=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $5 }'` + local line_control=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $6 }'` + local line_ack=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $7 }'` + local line_up=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $8 }'` + + if [ "${name}" != "${line_name}" ]; then + echo "FAILED: wrong name" + error=1 + fi + + if [ "${run}" != "${line_run}" ]; then + echo "FAILED: wrong run" + error=1 + fi + + if [ "${base}" != "${line_base}" ]; then + echo "FAILED: wrong base" + error=1 + fi + + if [ "${output}" != "${line_output}" ]; then + echo "FAILED: wrong output" + error=1 + fi + + if [ "${control}" != "${line_control}" ]; then + echo "FAILED: wrong control" + error=1 + fi + + if [ "${ack}" != "${line_ack}" ]; then + echo "FAILED: wrong ack" + error=1 + fi + + if [ "${up}" != "${line_up}" ]; then + echo "FAILED: wrong up" + error=1 + fi +} + +daemon_start() +{ + local config=$1 + local session=$2 + + perf daemon start --config ${config} + + # wait for the session to ping + local state="FAIL" + while [ "${state}" != "OK" ]; do + state=`perf daemon ping --config ${config} --session ${session} | awk '{ print $1 }'` + sleep 0.05 + done +} + +daemon_exit() +{ + local base=$1 + local config=$2 + + local line=`perf daemon --config ${config} -x: | head -1` + local pid=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $1 }'` + + # stop daemon + perf daemon stop --config ${config} + + # ... and wait for the pid to go away + tail --pid=${pid} -f /dev/null +} + +test_list() +{ + echo "test daemon list" + + local config=$(mktemp /tmp/perf.daemon.config.XXX) + local base=$(mktemp -d /tmp/perf.daemon.base.XXX) + + cat <<EOF > ${config} +[daemon] +base=BASE + +[session-size] +run = -e cpu-clock + +[session-time] +run = -e task-clock +EOF + + sed -i -e "s|BASE|${base}|" ${config} + + # start daemon + daemon_start ${config} size + + # check first line + # pid:daemon:base:base/output:base/lock + local line=`perf daemon --config ${config} -x: | head -1` + check_line_first ${line} daemon ${base} ${base}/output ${base}/lock "0" + + # check 1st session + # pid:size:-e cpu-clock:base/size:base/size/output:base/size/control:base/size/ack:0 + local line=`perf daemon --config ${config} -x: | head -2 | tail -1` + check_line_other "${line}" size "-e cpu-clock" ${base}/session-size \ + ${base}/session-size/output ${base}/session-size/control \ + ${base}/session-size/ack "0" + + # check 2nd session + # pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0 + local line=`perf daemon --config ${config} -x: | head -3 | tail -1` + check_line_other "${line}" time "-e task-clock" ${base}/session-time \ + ${base}/session-time/output ${base}/session-time/control \ + ${base}/session-time/ack "0" + + # stop daemon + daemon_exit ${base} ${config} + + rm -rf ${base} + rm -f ${config} +} + +test_reconfig() +{ + echo "test daemon reconfig" + + local config=$(mktemp /tmp/perf.daemon.config.XXX) + local base=$(mktemp -d /tmp/perf.daemon.base.XXX) + + # prepare config + cat <<EOF > ${config} +[daemon] +base=BASE + +[session-size] +run = -e cpu-clock + +[session-time] +run = -e task-clock +EOF + + sed -i -e "s|BASE|${base}|" ${config} + + # start daemon + daemon_start ${config} size + + # check 2nd session + # pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0 + local line=`perf daemon --config ${config} -x: | head -3 | tail -1` + check_line_other "${line}" time "-e task-clock" ${base}/session-time \ + ${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0" + local pid=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $1 }'` + + # prepare new config + local config_new=${config}.new + cat <<EOF > ${config_new} +[daemon] +base=BASE + +[session-size] +run = -e cpu-clock + +[session-time] +run = -e cpu-clock +EOF + + # TEST 1 - change config + + sed -i -e "s|BASE|${base}|" ${config_new} + cp ${config_new} ${config} + + # wait for old session to finish + tail --pid=${pid} -f /dev/null + + # wait for new one to start + local state="FAIL" + while [ "${state}" != "OK" ]; do + state=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'` + done + + # check reconfigured 2nd session + # pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0 + local line=`perf daemon --config ${config} -x: | head -3 | tail -1` + check_line_other "${line}" time "-e cpu-clock" ${base}/session-time \ + ${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0" + + # TEST 2 - empty config + + local config_empty=${config}.empty + cat <<EOF > ${config_empty} +[daemon] +base=BASE +EOF + + # change config + sed -i -e "s|BASE|${base}|" ${config_empty} + cp ${config_empty} ${config} + + # wait for sessions to finish + local state="OK" + while [ "${state}" != "FAIL" ]; do + state=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'` + done + + local state="OK" + while [ "${state}" != "FAIL" ]; do + state=`perf daemon ping --config ${config} --session size | awk '{ print $1 }'` + done + + local one=`perf daemon --config ${config} -x: | wc -l` + + if [ ${one} -ne "1" ]; then + echo "FAILED: wrong list output" + error=1 + fi + + # TEST 3 - config again + + cp ${config_new} ${config} + + # wait for size to start + local state="FAIL" + while [ "${state}" != "OK" ]; do + state=`perf daemon ping --config ${config} --session size | awk '{ print $1 }'` + done + + # wait for time to start + local state="FAIL" + while [ "${state}" != "OK" ]; do + state=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'` + done + + # stop daemon + daemon_exit ${base} ${config} + + rm -rf ${base} + rm -f ${config} + rm -f ${config_new} + rm -f ${config_empty} +} + +test_stop() +{ + echo "test daemon stop" + + local config=$(mktemp /tmp/perf.daemon.config.XXX) + local base=$(mktemp -d /tmp/perf.daemon.base.XXX) + + # prepare config + cat <<EOF > ${config} +[daemon] +base=BASE + +[session-size] +run = -e cpu-clock + +[session-time] +run = -e task-clock +EOF + + sed -i -e "s|BASE|${base}|" ${config} + + # start daemon + daemon_start ${config} size + + local pid_size=`perf daemon --config ${config} -x: | head -2 | tail -1 | awk 'BEGIN { FS = ":" } ; { print $1 }'` + local pid_time=`perf daemon --config ${config} -x: | head -3 | tail -1 | awk 'BEGIN { FS = ":" } ; { print $1 }'` + + # check that sessions are running + if [ ! -d "/proc/${pid_size}" ]; then + echo "FAILED: session size not up" + fi + + if [ ! -d "/proc/${pid_time}" ]; then + echo "FAILED: session time not up" + fi + + # stop daemon + daemon_exit ${base} ${config} + + # check that sessions are gone + if [ -d "/proc/${pid_size}" ]; then + echo "FAILED: session size still up" + fi + + if [ -d "/proc/${pid_time}" ]; then + echo "FAILED: session time still up" + fi + + rm -rf ${base} + rm -f ${config} +} + +test_signal() +{ + echo "test daemon signal" + + local config=$(mktemp /tmp/perf.daemon.config.XXX) + local base=$(mktemp -d /tmp/perf.daemon.base.XXX) + + # prepare config + cat <<EOF > ${config} +[daemon] +base=BASE + +[session-test] +run = -e cpu-clock --switch-output +EOF + + sed -i -e "s|BASE|${base}|" ${config} + + # start daemon + daemon_start ${config} test + + # send 2 signals + perf daemon signal --config ${config} --session test + perf daemon signal --config ${config} + + # stop daemon + daemon_exit ${base} ${config} + + # count is 2 perf.data for signals and 1 for perf record finished + count=`ls ${base}/session-test/ | grep perf.data | wc -l` + if [ ${count} -ne 3 ]; then + error=1 + echo "FAILED: perf data no generated" + fi + + rm -rf ${base} + rm -f ${config} +} + +test_ping() +{ + echo "test daemon ping" + + local config=$(mktemp /tmp/perf.daemon.config.XXX) + local base=$(mktemp -d /tmp/perf.daemon.base.XXX) + + # prepare config + cat <<EOF > ${config} +[daemon] +base=BASE + +[session-size] +run = -e cpu-clock + +[session-time] +run = -e task-clock +EOF + + sed -i -e "s|BASE|${base}|" ${config} + + # start daemon + daemon_start ${config} size + + size=`perf daemon ping --config ${config} --session size | awk '{ print $1 }'` + type=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'` + + if [ ${size} != "OK" -o ${type} != "OK" ]; then + error=1 + echo "FAILED: daemon ping failed" + fi + + # stop daemon + daemon_exit ${base} ${config} + + rm -rf ${base} + rm -f ${config} +} + +test_lock() +{ + echo "test daemon lock" + + local config=$(mktemp /tmp/perf.daemon.config.XXX) + local base=$(mktemp -d /tmp/perf.daemon.base.XXX) + + # prepare config + cat <<EOF > ${config} +[daemon] +base=BASE + +[session-size] +run = -e cpu-clock +EOF + + sed -i -e "s|BASE|${base}|" ${config} + + # start daemon + daemon_start ${config} size + + # start second daemon over the same config/base + failed=`perf daemon start --config ${config} 2>&1 | awk '{ print $1 }'` + + # check that we failed properly + if [ ${failed} != "failed:" ]; then + error=1 + echo "FAILED: daemon lock failed" + fi + + # stop daemon + daemon_exit ${base} ${config} + + rm -rf ${base} + rm -f ${config} +} + +error=0 + +test_list +test_reconfig +test_stop +test_signal +test_ping +test_lock + +exit ${error} |