test_brstack.sh 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/bin/sh
  2. # Check branch stack sampling
  3. # SPDX-License-Identifier: GPL-2.0
  4. # German Gomez <german.gomez@arm.com>, 2022
  5. shelldir=$(dirname "$0")
  6. # shellcheck source=lib/perf_has_symbol.sh
  7. . "${shelldir}"/lib/perf_has_symbol.sh
  8. # skip the test if the hardware doesn't support branch stack sampling
  9. # and if the architecture doesn't support filter types: any,save_type,u
  10. if ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then
  11. echo "skip: system doesn't support filter types: any,save_type,u"
  12. exit 2
  13. fi
  14. skip_test_missing_symbol brstack_bench
  15. TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
  16. TESTPROG="perf test -w brstack"
  17. cleanup() {
  18. rm -rf $TMPDIR
  19. }
  20. trap cleanup EXIT TERM INT
  21. test_user_branches() {
  22. echo "Testing user branch stack sampling"
  23. perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- ${TESTPROG} > /dev/null 2>&1
  24. perf script -i $TMPDIR/perf.data --fields brstacksym | xargs -n1 > $TMPDIR/perf.script
  25. # example of branch entries:
  26. # brstack_foo+0x14/brstack_bar+0x40/P/-/-/0/CALL
  27. set -x
  28. grep -E -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/IND_CALL/.*$" $TMPDIR/perf.script
  29. grep -E -m1 "^brstack_foo\+[^ ]*/brstack_bar\+[^ ]*/CALL/.*$" $TMPDIR/perf.script
  30. grep -E -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/CALL/.*$" $TMPDIR/perf.script
  31. grep -E -m1 "^brstack_bench\+[^ ]*/brstack_bar\+[^ ]*/CALL/.*$" $TMPDIR/perf.script
  32. grep -E -m1 "^brstack_bar\+[^ ]*/brstack_foo\+[^ ]*/RET/.*$" $TMPDIR/perf.script
  33. grep -E -m1 "^brstack_foo\+[^ ]*/brstack_bench\+[^ ]*/RET/.*$" $TMPDIR/perf.script
  34. grep -E -m1 "^brstack_bench\+[^ ]*/brstack_bench\+[^ ]*/COND/.*$" $TMPDIR/perf.script
  35. grep -E -m1 "^brstack\+[^ ]*/brstack\+[^ ]*/UNCOND/.*$" $TMPDIR/perf.script
  36. set +x
  37. # some branch types are still not being tested:
  38. # IND COND_CALL COND_RET SYSCALL SYSRET IRQ SERROR NO_TX
  39. }
  40. # first argument <arg0> is the argument passed to "--branch-stack <arg0>,save_type,u"
  41. # second argument are the expected branch types for the given filter
  42. test_filter() {
  43. test_filter_filter=$1
  44. test_filter_expect=$2
  45. echo "Testing branch stack filtering permutation ($test_filter_filter,$test_filter_expect)"
  46. perf record -o $TMPDIR/perf.data --branch-filter $test_filter_filter,save_type,u -- ${TESTPROG} > /dev/null 2>&1
  47. perf script -i $TMPDIR/perf.data --fields brstack | xargs -n1 > $TMPDIR/perf.script
  48. # fail if we find any branch type that doesn't match any of the expected ones
  49. # also consider UNKNOWN branch types (-)
  50. if grep -E -vm1 "^[^ ]*/($test_filter_expect|-|( *))/.*$" $TMPDIR/perf.script; then
  51. return 1
  52. fi
  53. }
  54. set -e
  55. test_user_branches
  56. test_filter "any_call" "CALL|IND_CALL|COND_CALL|SYSCALL|IRQ"
  57. test_filter "call" "CALL|SYSCALL"
  58. test_filter "cond" "COND"
  59. test_filter "any_ret" "RET|COND_RET|SYSRET|ERET"
  60. test_filter "call,cond" "CALL|SYSCALL|COND"
  61. test_filter "any_call,cond" "CALL|IND_CALL|COND_CALL|IRQ|SYSCALL|COND"
  62. test_filter "cond,any_call,any_ret" "COND|CALL|IND_CALL|COND_CALL|SYSCALL|IRQ|RET|COND_RET|SYSRET|ERET"