diff options
Diffstat (limited to 'tools/perf/tests')
27 files changed, 325 insertions, 134 deletions
diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 98956e0e0765..e7adf60be721 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -16,7 +16,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) bm = bitmap_zalloc(nbits); if (map && bm) { - int i; + unsigned int i; struct perf_cpu cpu; perf_cpu_map__for_each_cpu(cpu, i, map) diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 3faeb5b6fe0b..f580ba7486b1 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -36,7 +36,7 @@ static int fd3; static int overflows; static int overflows_2; -volatile long the_var; +static volatile long the_var; /* diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 5927d1ea20e2..47043a3a2fb4 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -4,6 +4,7 @@ #include <linux/kernel.h> #include <linux/rbtree.h> #include <linux/types.h> +#include <linux/zalloc.h> #include <inttypes.h> #include <stdlib.h> #include <unistd.h> diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 2354246afc5a..b051dce2cd86 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -156,7 +156,8 @@ static int test__cpu_map_print(struct test_suite *test __maybe_unused, int subte return 0; } -static int __test__cpu_map_merge(const char *lhs, const char *rhs, int nr, const char *expected) +static int __test__cpu_map_merge(const char *lhs, const char *rhs, unsigned int nr, + const char *expected) { struct perf_cpu_map *a = perf_cpu_map__new(lhs); struct perf_cpu_map *b = perf_cpu_map__new(rhs); @@ -204,7 +205,8 @@ static int test__cpu_map_merge(struct test_suite *test __maybe_unused, return ret; } -static int __test__cpu_map_intersect(const char *lhs, const char *rhs, int nr, const char *expected) +static int __test__cpu_map_intersect(const char *lhs, const char *rhs, unsigned int nr, + const char *expected) { struct perf_cpu_map *a = perf_cpu_map__new(lhs); struct perf_cpu_map *b = perf_cpu_map__new(rhs); diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index a1fff4203b75..46bc3f597260 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -58,7 +58,7 @@ struct test_data_offset { int size; }; -struct test_data_offset offsets[] = { +static struct test_data_offset offsets[] = { /* Fill first cache page. */ { .offset = 10, diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index cb9e6de2e033..facc65e29f20 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -8,6 +8,7 @@ #include "header.h" #include "machine.h" #include "util/synthetic-events.h" +#include "target.h" #include "tool.h" #include "tests.h" #include "debug.h" @@ -81,7 +82,8 @@ static int test__event_update(struct test_suite *test __maybe_unused, int subtes { struct evsel *evsel; struct event_name tmp; - struct evlist *evlist = evlist__new_default(); + struct target target = {}; + struct evlist *evlist = evlist__new_default(&target, /*sample_callchains=*/false); TEST_ASSERT_VAL("failed to get evlist", evlist); diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgroup.c index c7b32a220ca1..dd547f2f77cc 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -8,6 +8,7 @@ #include "parse-events.h" #include "pmu-events/pmu-events.h" #include "pfm.h" +#include "target.h" #include <subcmd/parse-options.h> #include <stdio.h> #include <stdlib.h> @@ -99,7 +100,8 @@ out: for (i = 0; i < nr_events; i++) static int expand_default_events(void) { int ret; - struct evlist *evlist = evlist__new_default(); + struct target target = {}; + struct evlist *evlist = evlist__new_default(&target, /*sample_callchains=*/false); TEST_ASSERT_VAL("failed to get evlist", evlist); diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 3eb9ef8d7ec6..606aa926a8fc 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -81,7 +81,7 @@ static int add_hist_entries(struct hists *hists, struct machine *machine) { struct addr_location al; struct evsel *evsel = hists_to_evsel(hists); - struct perf_sample sample = { .period = 1000, }; + struct perf_sample sample = { .evsel = evsel, .period = 1000, }; size_t i; addr_location__init(&al); diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 1cebd20cc91c..cc6b26e373d1 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -70,6 +70,7 @@ static int add_hist_entries(struct evlist *evlist, }; struct hists *hists = evsel__hists(evsel); + sample.evsel = evsel; /* make sure it has no filter at first */ hists->thread_filter = NULL; hists->dso_filter = NULL; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index ee5ec8bda60e..7818950d786e 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -51,7 +51,7 @@ static int add_hist_entries(struct hists *hists, struct machine *machine) { struct addr_location al; struct evsel *evsel = hists_to_evsel(hists); - struct perf_sample sample = { .period = 100, }; + struct perf_sample sample = { .evsel = evsel, .period = 100, }; size_t i; addr_location__init(&al); diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index a0e88c496107..7ce1ad7b6ce5 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -30,7 +30,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) if (map && bm) { struct perf_cpu cpu; - int i; + unsigned int i; perf_cpu_map__for_each_cpu(cpu, i, map) __set_bit(cpu.cpu, bm); diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 3644d6f52c07..0be43f8db3bd 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -22,7 +22,8 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { - int err = TEST_FAIL, fd, idx; + int err = TEST_FAIL, fd; + unsigned int idx; struct perf_cpu cpu; struct perf_cpu_map *cpus; struct evsel *evsel; diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 1d3cc224fbc2..05c3e899b425 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1796,31 +1796,38 @@ static bool test__acr_valid(void) static int test__ratio_to_prev(struct evlist *evlist) { - struct evsel *evsel; + struct evsel *evsel, *leader; TEST_ASSERT_VAL("wrong number of entries", 2 * perf_pmus__num_core_pmus() == evlist->core.nr_entries); - evlist__for_each_entry(evlist, evsel) { - if (!perf_pmu__has_format(evsel->pmu, "acr_mask")) - return TEST_OK; - - if (evsel == evlist__first(evlist)) { - TEST_ASSERT_VAL("wrong config2", 0 == evsel->core.attr.config2); - TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2); - TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0); - TEST_ASSERT_EVSEL("unexpected event", - evsel__match(evsel, HARDWARE, HW_CPU_CYCLES), - evsel); - } else { - TEST_ASSERT_VAL("wrong config2", 0 == evsel->core.attr.config2); - TEST_ASSERT_VAL("wrong leader", !evsel__is_group_leader(evsel)); - TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 0); - TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1); - TEST_ASSERT_EVSEL("unexpected event", - evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS), - evsel); + evlist__for_each_entry(evlist, evsel) { + if (evsel != evsel__leader(evsel) || + !perf_pmu__has_format(evsel->pmu, "acr_mask")) { + continue; } + leader = evsel; + /* cycles */ + TEST_ASSERT_VAL("wrong config2", 0 == leader->core.attr.config2); + TEST_ASSERT_VAL("wrong core.nr_members", leader->core.nr_members == 2); + TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(leader) == 0); + TEST_ASSERT_EVSEL("unexpected event", + evsel__match(leader, HARDWARE, HW_CPU_CYCLES), + leader); + /* + * The period value gets configured within evlist__config, + * while this test executes only parse events method. + */ + TEST_ASSERT_VAL("wrong period", 0 == leader->core.attr.sample_period); + + /* instructions/period=200000,ratio-to-prev=2.0/ */ + evsel = evsel__next(evsel); + TEST_ASSERT_VAL("wrong config2", 0 == evsel->core.attr.config2); + TEST_ASSERT_VAL("wrong leader", evsel__has_leader(evsel, leader)); + TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 0); + TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1); + TEST_ASSERT_EVSEL("unexpected event", + evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS), + evsel); /* * The period value gets configured within evlist__config, * while this test executes only parse events method. diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index efbd9cd60c63..ad44cc68820b 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -84,8 +84,11 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest CPU_ZERO_S(cpu_mask_size, cpu_mask); perf_sample__init(&sample, /*all=*/false); - if (evlist == NULL) /* Fallback for kernels lacking PERF_COUNT_SW_DUMMY */ - evlist = evlist__new_default(); + if (evlist == NULL) { /* Fallback for kernels lacking PERF_COUNT_SW_DUMMY */ + struct target target = {}; + + evlist = evlist__new_default(&target, /*sample_callchains=*/false); + } if (evlist == NULL) { pr_debug("Not enough memory to create evlist\n"); @@ -297,6 +300,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest } perf_mmap__consume(&md->core); + perf_sample__exit(&sample); } perf_mmap__read_done(&md->core); } diff --git a/tools/perf/tests/shell/data_type_profiling.sh b/tools/perf/tests/shell/data_type_profiling.sh index 2a7f8f7c42d0..eca694600a04 100755 --- a/tools/perf/tests/shell/data_type_profiling.sh +++ b/tools/perf/tests/shell/data_type_profiling.sh @@ -8,13 +8,17 @@ set -e # data type profiling manifestation # Values in testtypes and testprogs should match -testtypes=("# data-type: struct Buf" "# data-type: struct _buf") +testtypes=("# data-type: struct Buf" "# data-type: struct buf") testprogs=("perf test -w code_with_type" "perf test -w datasym") err=0 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) perfout=$(mktemp /tmp/__perf_test.perf.out.XXXXX) +# Check for support of perf mem before trap handler +perf mem record -o /dev/null -- true 2>&1 | \ + grep -q "failed: no PMU supports the memory events" && exit 2 + cleanup() { rm -rf "${perfdata}" "${perfout}" rm -rf "${perfdata}".old diff --git a/tools/perf/tests/shell/kwork.sh b/tools/perf/tests/shell/kwork.sh new file mode 100755 index 000000000000..42bfd9382816 --- /dev/null +++ b/tools/perf/tests/shell/kwork.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# perf kwork tests +# SPDX-License-Identifier: GPL-2.0 + +set -e + +# Root permissions required for tracing events. +if [ "$(id -u)" != 0 ]; then + echo "[Skip] No root permission" + exit 2 +fi + +err=0 +perfdata=$(mktemp /tmp/__perf_test_kwork.perf.data.XXXXX) + +cleanup() { + rm -f "${perfdata}" + rm -f "${perfdata}".old + + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup EXIT TERM INT + +test_kwork_record() { + echo "Kwork record" + perf kwork record -o "${perfdata}" -- sleep 1 + echo "Kwork record [Success]" +} + +test_kwork_report() { + echo "Kwork report" + if ! perf kwork report -i "${perfdata}" | grep -q "Kwork Name"; then + echo "Kwork report [Failed missing output]" + err=1 + fi + echo "Kwork report [Success]" +} + +test_kwork_latency() { + echo "Kwork latency" + if ! perf kwork latency -i "${perfdata}" | grep -q "Avg delay"; then + echo "Kwork latency [Failed missing output]" + err=1 + fi + echo "Kwork latency [Success]" +} + +test_kwork_timehist() { + echo "Kwork timehist" + if ! perf kwork timehist -i "${perfdata}" | grep -q "Kwork name"; then + echo "Kwork timehist [Failed missing output]" + err=1 + fi + echo "Kwork timehist [Success]" +} + +test_kwork_top() { + echo "Kwork top" + if ! perf kwork top -i "${perfdata}" | grep -q "COMMAND"; then + echo "Kwork top [Failed missing output]" + err=1 + fi + echo "Kwork top [Success]" +} + +test_kwork_record +test_kwork_report +test_kwork_latency +test_kwork_timehist +test_kwork_top + +cleanup +exit $err diff --git a/tools/perf/tests/shell/perf_sched_stats.sh b/tools/perf/tests/shell/perf_sched_stats.sh index 2b1410b050d0..f13eb0a75b76 100755 --- a/tools/perf/tests/shell/perf_sched_stats.sh +++ b/tools/perf/tests/shell/perf_sched_stats.sh @@ -4,10 +4,34 @@ set -e +if [ "$(id -u)" != 0 ]; then + echo "[Skip] No root permission" + exit 2 +fi + +perfdata=$(mktemp /tmp/__perf_test_sched_stats.perf.data.XXXXX) +perfdata2=$(mktemp /tmp/__perf_test_sched_stats.perf.data.XXXXX) + +cleanup() { + rm -f "${perfdata}" + rm -f "${perfdata}".old + rm -f "${perfdata2}" + rm -f "${perfdata2}".old + + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup EXIT TERM INT + err=0 test_perf_sched_stats_record() { echo "Basic perf sched stats record test" - if ! perf sched stats record true 2>&1 | \ + if ! perf sched stats record -o "${perfdata}" true 2>&1 | \ grep -E -q "[ perf sched stats: Wrote samples to perf.data ]" then echo "Basic perf sched stats record test [Failed]" @@ -19,15 +43,13 @@ test_perf_sched_stats_record() { test_perf_sched_stats_report() { echo "Basic perf sched stats report test" - perf sched stats record true > /dev/null - if ! perf sched stats report 2>&1 | grep -E -q "Description" + perf sched stats record -o "${perfdata}" true > /dev/null + if ! perf sched stats report -i "${perfdata}" 2>&1 | grep -E -q "Description" then echo "Basic perf sched stats report test [Failed]" err=1 - rm perf.data return fi - rm perf.data echo "Basic perf sched stats report test [Success]" } @@ -44,16 +66,14 @@ test_perf_sched_stats_live() { test_perf_sched_stats_diff() { echo "Basic perf sched stats diff test" - perf sched stats record true > /dev/null - perf sched stats record true > /dev/null - if ! perf sched stats diff > /dev/null + perf sched stats record -o "${perfdata}" true > /dev/null + perf sched stats record -o "${perfdata2}" true > /dev/null + if ! perf sched stats diff "${perfdata}" "${perfdata2}" > /dev/null then echo "Basic perf sched stats diff test [Failed]" err=1 - rm perf.data.old perf.data return fi - rm perf.data.old perf.data echo "Basic perf sched stats diff test [Success]" } @@ -61,4 +81,6 @@ test_perf_sched_stats_record test_perf_sched_stats_report test_perf_sched_stats_live test_perf_sched_stats_diff + +cleanup exit $err diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh index ab99bef556bf..eca629ee83f0 100755 --- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh @@ -22,9 +22,9 @@ event_pattern='probe_libc:inet_pton(_[[:digit:]]+)?' add_libc_inet_pton_event() { - event_name=$(perf probe -f -x $libc -a inet_pton 2>&1 | tail -n +2 | head -n -5 | \ + event_name=$(perf probe -f -x $libc -a inet_pton 2>&1 | \ awk -v ep="$event_pattern" -v l="$libc" '$0 ~ ep && $0 ~ \ - ("\\(on inet_pton in " l "\\)") {print $1}') + ("\\(on inet_pton in " l "\\)") {print $1}' | head -n 1) if [ $? -ne 0 ] || [ -z "$event_name" ] ; then printf "FAIL: could not add event\n" @@ -40,12 +40,12 @@ trace_libc_inet_pton_backtrace() { echo ".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected case "$(uname -m)" in s390x) - eventattr='call-graph=dwarf,max-stack=4' + eventattr='call-graph=dwarf,max-stack=8' echo "((__GI_)?getaddrinfo|text_to_binary_address)\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected echo "(gaih_inet|main)\+0x[[:xdigit:]]+[[:space:]]\(inlined|.*/bin/ping.*\)$" >> $expected ;; *) - eventattr='max-stack=4' + eventattr='call-graph=dwarf,max-stack=8' echo ".*(\+0x[[:xdigit:]]+|\[unknown\])[[:space:]]\(.*/bin/ping.*\)$" >> $expected ;; esac diff --git a/tools/perf/tests/shell/stat_bpf_counters.sh b/tools/perf/tests/shell/stat_bpf_counters.sh index f43e28a136d3..35463358b273 100755 --- a/tools/perf/tests/shell/stat_bpf_counters.sh +++ b/tools/perf/tests/shell/stat_bpf_counters.sh @@ -41,8 +41,14 @@ check_counts() test_bpf_counters() { printf "Testing --bpf-counters " - base_instructions=$(perf stat --no-big-num -e instructions -- $workload 2>&1 | awk '/instructions/ {print $1}') - bpf_instructions=$(perf stat --no-big-num --bpf-counters -e instructions -- $workload 2>&1 | awk '/instructions/ {print $1}') + base_instructions=$(perf stat --no-big-num -e instructions -- $workload 2>&1 | \ + awk -v i=0 -v c=0 '/instructions/ { \ + if ($1 != "<not") { i++; c += $1 } \ + } END { if (i > 0) printf "%.0f", c; else print "<not" }') + bpf_instructions=$(perf stat --no-big-num --bpf-counters -e instructions -- $workload 2>&1 | \ + awk -v i=0 -v c=0 '/instructions/ { \ + if ($1 != "<not") { i++; c += $1 } \ + } END { if (i > 0) printf "%.0f", c; else print "<not" }') check_counts $base_instructions $bpf_instructions compare_number $base_instructions $bpf_instructions echo "[Success]" @@ -52,8 +58,14 @@ test_bpf_modifier() { printf "Testing bpf event modifier " stat_output=$(perf stat --no-big-num -e instructions/name=base_instructions/,instructions/name=bpf_instructions/b -- $workload 2>&1) - base_instructions=$(echo "$stat_output"| awk '/base_instructions/ {print $1}') - bpf_instructions=$(echo "$stat_output"| awk '/bpf_instructions/ {print $1}') + base_instructions=$(echo "$stat_output"| \ + awk -v i=0 -v c=0 '/base_instructions/ { \ + if ($1 != "<not") { i++; c += $1 } \ + } END { if (i > 0) printf "%.0f", c; else print "<not" }') + bpf_instructions=$(echo "$stat_output"| \ + awk -v i=0 -v c=0 '/bpf_instructions/ { \ + if ($1 != "<not") { i++; c += $1 } \ + } END { if (i > 0) printf "%.0f", c; else print "<not" }') check_counts $base_instructions $bpf_instructions compare_number $base_instructions $bpf_instructions echo "[Success]" diff --git a/tools/perf/tests/shell/test_brstack.sh b/tools/perf/tests/shell/test_brstack.sh index 85233d435be6..eb5837f82e39 100755 --- a/tools/perf/tests/shell/test_brstack.sh +++ b/tools/perf/tests/shell/test_brstack.sh @@ -38,9 +38,13 @@ is_arm64() { [ "$(uname -m)" = "aarch64" ]; } +has_kaslr_bug() { + [ "$(uname -m)" != "aarch64" ]; +} + check_branches() { if ! tr -s ' ' '\n' < "$TMPDIR/perf.script" | grep -E -m1 -q "$1"; then - echo "Branches missing $1" + echo "ERROR: Branches missing $1" err=1 fi } @@ -48,6 +52,8 @@ check_branches() { test_user_branches() { echo "Testing user branch stack sampling" + start_err=$err + err=0 perf record -o "$TMPDIR/perf.data" --branch-filter any,save_type,u -- ${TESTPROG} > "$TMPDIR/record.txt" 2>&1 perf script -i "$TMPDIR/perf.data" --fields brstacksym > "$TMPDIR/perf.script" @@ -73,59 +79,88 @@ test_user_branches() { perf script -i "$TMPDIR/perf.data" --fields brstack | \ tr ' ' '\n' > "$TMPDIR/perf.script" - # There should be no kernel addresses with the u option, in either - # source or target addresses. - if grep -E -m1 "0x[89a-f][0-9a-f]{15}" $TMPDIR/perf.script; then - echo "ERROR: Kernel address found in user mode" + # There should be no kernel addresses in the target with the u option. + local regex="0x[89a-f][0-9a-f]{15}" + if has_kaslr_bug; then + # If the system has a kaslr bug that may leak kernel addresses + # in the source of something like an ERET/SYSRET. Make the regex + # more specific and just check the target address is in user + # code. + regex="^0x[0-9a-f]{0,16}/0x[89a-f][0-9a-f]{15}/" + fi + if grep -q -E -m1 "$regex" $TMPDIR/perf.script; then + echo "Testing user branch stack sampling [Failed kernel address found in user mode]" err=1 fi # some branch types are still not being tested: # IND COND_CALL COND_RET SYSRET SERROR NO_TX + if [ $err -eq 0 ]; then + echo "Testing user branch stack sampling [Passed]" + err=$start_err + else + echo "Testing user branch stack sampling [Failed]" + fi } test_trap_eret_branches() { echo "Testing trap & eret branches" + if ! is_arm64; then - echo "skip: not arm64" + echo "Testing trap & eret branches [Skipped not arm64]" + return + fi + start_err=$err + err=0 + perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u,k -- \ + perf test -w traploop 1000 > "$TMPDIR/record.txt" 2>&1 + perf script -i $TMPDIR/perf.data --fields brstacksym | \ + tr ' ' '\n' > $TMPDIR/perf.script + + # BRBINF<n>.TYPE == TRAP are mapped to PERF_BR_IRQ by the BRBE driver + check_branches "^trap_bench\+[^ ]+/[^ ]/IRQ/" + check_branches "^[^ ]+/trap_bench\+[^ ]+/ERET/" + if [ $err -eq 0 ]; then + echo "Testing trap & eret branches [Passed]" + err=$start_err else - perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u,k -- \ - perf test -w traploop 1000 - perf script -i $TMPDIR/perf.data --fields brstacksym | \ - tr ' ' '\n' > $TMPDIR/perf.script - - # BRBINF<n>.TYPE == TRAP are mapped to PERF_BR_IRQ by the BRBE driver - check_branches "^trap_bench\+[^ ]+/[^ ]/IRQ/" - check_branches "^[^ ]+/trap_bench\+[^ ]+/ERET/" + echo "Testing trap & eret branches [Failed]" fi } test_kernel_branches() { - echo "Testing that k option only includes kernel source addresses" + echo "Testing kernel branch sampling" - if ! perf record --branch-filter any,k -o- -- true > /dev/null; then - echo "skip: not enough privileges" + if ! perf record --branch-filter any,k -o- -- true > "$TMPDIR/record.txt" 2>&1; then + echo "Testing that k option [Skipped not enough privileges]" + return + fi + start_err=$err + err=0 + perf record -o $TMPDIR/perf.data --branch-filter any,k -- \ + perf bench syscall basic --loop 1000 > "$TMPDIR/record.txt" 2>&1 + perf script -i $TMPDIR/perf.data --fields brstack | \ + tr ' ' '\n' > $TMPDIR/perf.script + + # Example of branch entries: + # "0xffffffff93bda241/0xffffffff93bda20f/M/-/-/..." + # Source addresses come first in user or kernel code. Next is the target + # address that must be in the kernel. + + # Look for source addresses with top bit set + if ! grep -q -E -m1 "^0x[89a-f][0-9a-f]{15}" $TMPDIR/perf.script; then + echo "Testing kernel branch sampling [Failed kernel branches missing]" + err=1 + fi + # Look for no target addresses without top bit set + if grep -q -E -m1 "^0x[0-9a-f]{0,16}/0x[0-7][0-9a-f]{1,15}/" $TMPDIR/perf.script; then + echo "Testing kernel branch sampling [Failed user branches found]" + err=1 + fi + if [ $err -eq 0 ]; then + echo "Testing kernel branch sampling [Passed]" + err=$start_err else - perf record -o $TMPDIR/perf.data --branch-filter any,k -- \ - perf bench syscall basic --loop 1000 - perf script -i $TMPDIR/perf.data --fields brstack | \ - tr ' ' '\n' > $TMPDIR/perf.script - - # Example of branch entries: - # "0xffffffff93bda241/0xffffffff93bda20f/M/-/-/..." - # Source addresses come first and target address can be either - # userspace or kernel even with k option, as long as the source - # is in kernel. - - #Look for source addresses with top bit set - if ! grep -E -m1 "^0x[89a-f][0-9a-f]{15}" $TMPDIR/perf.script; then - echo "ERROR: Kernel branches missing" - err=1 - fi - # Look for no source addresses without top bit set - if grep -E -m1 "^0x[0-7][0-9a-f]{0,15}" $TMPDIR/perf.script; then - echo "ERROR: User branches found with kernel filter" - err=1 - fi + echo "Testing kernel branch sampling [Failed]" fi } @@ -136,14 +171,15 @@ test_filter() { test_filter_expect=$2 echo "Testing branch stack filtering permutation ($test_filter_filter,$test_filter_expect)" - perf record -o "$TMPDIR/perf.data" --branch-filter "$test_filter_filter,save_type,u" -- ${TESTPROG} > "$TMPDIR/record.txt" 2>&1 + perf record -o "$TMPDIR/perf.data" --branch-filter "$test_filter_filter,save_type,u" -- \ + ${TESTPROG} > "$TMPDIR/record.txt" 2>&1 perf script -i "$TMPDIR/perf.data" --fields brstack > "$TMPDIR/perf.script" # fail if we find any branch type that doesn't match any of the expected ones # also consider UNKNOWN branch types (-) if [ ! -s "$TMPDIR/perf.script" ] then - echo "Empty script output" + echo "Testing branch stack filtering [Failed empty script output]" err=1 return fi @@ -154,26 +190,36 @@ test_filter() { > "$TMPDIR/perf.script-filtered" || true if [ -s "$TMPDIR/perf.script-filtered" ] then - echo "Unexpected branch filter in script output" + echo "Testing branch stack filtering [Failed unexpected branch filter]" cat "$TMPDIR/perf.script" err=1 return fi + echo "Testing branch stack filtering [Passed]" } test_syscall() { echo "Testing syscalls" # skip if perf doesn't have enough privileges - if ! perf record --branch-filter any,k -o- -- true > /dev/null; then - echo "skip: not enough privileges" + if ! perf record --branch-filter any,k -o- -- true > "$TMPDIR/record.txt" 2>&1; then + echo "Testing syscalls [Skipped: not enough privileges]" + return + fi + start_err=$err + err=0 + perf record -o $TMPDIR/perf.data --branch-filter \ + any_call,save_type,u,k -c 10007 -- \ + perf bench syscall basic --loop 8000 > "$TMPDIR/record.txt" 2>&1 + perf script -i $TMPDIR/perf.data --fields brstacksym | \ + tr ' ' '\n' > $TMPDIR/perf.script + + check_branches "getppid[^ ]*/SYSCALL/" + + if [ $err -eq 0 ]; then + echo "Testing syscalls [Passed]" + err=$start_err else - perf record -o $TMPDIR/perf.data --branch-filter \ - any_call,save_type,u,k -c 10000 -- \ - perf bench syscall basic --loop 1000 - perf script -i $TMPDIR/perf.data --fields brstacksym | \ - tr ' ' '\n' > $TMPDIR/perf.script - - check_branches "getppid[^ ]*/SYSCALL/" + echo "Testing syscalls [Failed]" fi } set -e diff --git a/tools/perf/tests/shell/test_task_analyzer.sh b/tools/perf/tests/shell/test_task_analyzer.sh index e194fcf61df3..0314412e63b4 100755 --- a/tools/perf/tests/shell/test_task_analyzer.sh +++ b/tools/perf/tests/shell/test_task_analyzer.sh @@ -3,6 +3,11 @@ # SPDX-License-Identifier: GPL-2.0 tmpdir=$(mktemp -d /tmp/perf-script-task-analyzer-XXXXX) +# TODO: perf script report only supports input from the CWD perf.data file, make +# it support input from any file. +perfdata="perf.data" +csv="$tmpdir/csv" +csvsummary="$tmpdir/csvsummary" err=0 # set PERF_EXEC_PATH to find scripts in the source directory @@ -15,11 +20,10 @@ fi export ASAN_OPTIONS=detect_leaks=0 cleanup() { - rm -f perf.data - rm -f perf.data.old - rm -f csv - rm -f csvsummary + rm -f "${perfdata}" + rm -f "${perfdata}".old rm -rf "$tmpdir" + trap - exit term int } @@ -61,10 +65,10 @@ skip_no_probe_record_support() { prepare_perf_data() { # 1s should be sufficient to catch at least some switches - perf record -e sched:sched_switch -a -- sleep 1 > /dev/null 2>&1 + perf record -e sched:sched_switch -a -o "${perfdata}" -- sleep 1 > /dev/null 2>&1 # check if perf data file got created in above step. - if [ ! -e "perf.data" ]; then - printf "FAIL: perf record failed to create \"perf.data\" \n" + if [ ! -e "${perfdata}" ]; then + printf "FAIL: perf record failed to create \"${perfdata}\" \n" return 1 fi } @@ -130,28 +134,28 @@ test_extended_times_summary_ns() { } test_csv() { - perf script report task-analyzer --csv csv > /dev/null - check_exec_0 "perf script report task-analyzer --csv csv" - find_str_or_fail "Comm;" csv "${FUNCNAME[0]}" + perf script report task-analyzer --csv "${csv}" > /dev/null + check_exec_0 "perf script report task-analyzer --csv ${csv}" + find_str_or_fail "Comm;" "${csv}" "${FUNCNAME[0]}" } test_csv_extended_times() { - perf script report task-analyzer --csv csv --extended-times > /dev/null - check_exec_0 "perf script report task-analyzer --csv csv --extended-times" - find_str_or_fail "Out-Out;" csv "${FUNCNAME[0]}" + perf script report task-analyzer --csv "${csv}" --extended-times > /dev/null + check_exec_0 "perf script report task-analyzer --csv ${csv} --extended-times" + find_str_or_fail "Out-Out;" "${csv}" "${FUNCNAME[0]}" } test_csvsummary() { - perf script report task-analyzer --csv-summary csvsummary > /dev/null - check_exec_0 "perf script report task-analyzer --csv-summary csvsummary" - find_str_or_fail "Comm;" csvsummary "${FUNCNAME[0]}" + perf script report task-analyzer --csv-summary "${csvsummary}" > /dev/null + check_exec_0 "perf script report task-analyzer --csv-summary ${csvsummary}" + find_str_or_fail "Comm;" "${csvsummary}" "${FUNCNAME[0]}" } test_csvsummary_extended() { - perf script report task-analyzer --csv-summary csvsummary --summary-extended \ + perf script report task-analyzer --csv-summary "${csvsummary}" --summary-extended \ >/dev/null - check_exec_0 "perf script report task-analyzer --csv-summary csvsummary --summary-extended" - find_str_or_fail "Out-Out;" csvsummary "${FUNCNAME[0]}" + check_exec_0 "perf script report task-analyzer --csv-summary ${csvsummary} --summary-extended" + find_str_or_fail "Out-Out;" "${csvsummary}" "${FUNCNAME[0]}" } skip_no_probe_record_support diff --git a/tools/perf/tests/shell/trace_btf_general.sh b/tools/perf/tests/shell/trace_btf_general.sh index ef2da806be6b..7a94a5743924 100755 --- a/tools/perf/tests/shell/trace_btf_general.sh +++ b/tools/perf/tests/shell/trace_btf_general.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf trace BTF general tests +# perf trace BTF general tests (exclusive) # SPDX-License-Identifier: GPL-2.0 err=0 diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 15791fcb76b2..72a8289e846d 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -239,11 +239,13 @@ static int add_event(struct evlist *evlist, struct list_head *events, if (!sample.time) { pr_debug("event with no time\n"); + perf_sample__exit(&sample); return -1; } node->event_time = sample.time; + perf_sample__exit(&sample); return 0; } diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index 54209592168d..877868107455 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -9,7 +9,6 @@ #include "debug.h" #include "event.h" #include "util/synthetic-events.h" -#include <linux/zalloc.h> #include <perf/event.h> #include <internal/threadmap.h> diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index ec01150d208d..f54502ebef4b 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -9,6 +9,7 @@ #include "evlist.h" #include "debug.h" #include "pmus.h" +#include "target.h" #include <linux/err.h> #define TEMPL "/tmp/perf-test-XXXXXX" @@ -37,11 +38,12 @@ static int session_write_header(char *path) .path = path, .mode = PERF_DATA_MODE_WRITE, }; + struct target target = {}; session = perf_session__new(&data, NULL); TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); - session->evlist = evlist__new_default(); + session->evlist = evlist__new_default(&target, /*sample_callchains=*/false); TEST_ASSERT_VAL("can't get evlist", session->evlist); session->evlist->session = session; @@ -52,7 +54,8 @@ static int session_write_header(char *path) session->header.data_size += DATA_SIZE; TEST_ASSERT_VAL("failed to write header", - !perf_session__write_header(session, session->evlist, data.file.fd, true)); + !perf_session__write_header(session, session->evlist, + perf_data__fd(&data), true)); evlist__delete(session->evlist); perf_session__delete(session); @@ -67,7 +70,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) .path = path, .mode = PERF_DATA_MODE_READ, }; - int i; + unsigned int i; struct aggr_cpu_id id; struct perf_cpu cpu; struct perf_env *env; @@ -114,7 +117,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) TEST_ASSERT_VAL("Session header CPU map not set", env->cpu); - for (i = 0; i < env->nr_cpus_avail; i++) { + for (i = 0; i < (unsigned int)env->nr_cpus_avail; i++) { cpu.cpu = i; if (!perf_cpu_map__has(map, cpu)) continue; diff --git a/tools/perf/tests/workloads/datasym.c b/tools/perf/tests/workloads/datasym.c index 1d0b7d64e1ba..19242c7255c0 100644 --- a/tools/perf/tests/workloads/datasym.c +++ b/tools/perf/tests/workloads/datasym.c @@ -4,14 +4,14 @@ #include <linux/compiler.h> #include "../tests.h" -typedef struct _buf { +struct buf { char data1; char reserved[55]; char data2; -} buf __attribute__((aligned(64))); +} __attribute__((aligned(64))); /* volatile to try to avoid the compiler seeing reserved as unused. */ -static volatile buf workload_datasym_buf1 = { +static volatile struct buf workload_datasym_buf1 = { /* to have this in the data section */ .reserved[0] = 1, }; diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index 6c178985e37f..69b31f00eed0 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -22,11 +22,11 @@ do { \ #ifdef __i386__ /* Only breakpoint length less-than 8 has hardware support on i386. */ -volatile u32 data1; +static volatile u32 data1; #else -volatile u64 data1; +static volatile u64 data1; #endif -volatile u8 data2[3]; +static volatile u8 data2[3]; #ifndef __s390x__ static int wp_read(int fd, long long *count, int size) |
