stat+std_output.sh 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/bin/bash
  2. # perf stat STD output linter
  3. # SPDX-License-Identifier: GPL-2.0
  4. # Tests various perf stat STD output commands for
  5. # default event and metricgroup
  6. set -e
  7. # shellcheck source=lib/stat_output.sh
  8. . "$(dirname $0)"/lib/stat_output.sh
  9. stat_output=$(mktemp /tmp/__perf_test.stat_output.std.XXXXX)
  10. event_name=(cpu-clock task-clock context-switches cpu-migrations page-faults stalled-cycles-frontend stalled-cycles-backend cycles instructions branches branch-misses)
  11. event_metric=("CPUs utilized" "CPUs utilized" "/sec" "/sec" "/sec" "frontend cycles idle" "backend cycles idle" "GHz" "insn per cycle" "/sec" "of all branches")
  12. skip_metric=("stalled cycles per insn" "tma_" "retiring" "frontend_bound" "bad_speculation" "backend_bound")
  13. cleanup() {
  14. rm -f "${stat_output}"
  15. trap - EXIT TERM INT
  16. }
  17. trap_cleanup() {
  18. cleanup
  19. exit 1
  20. }
  21. trap trap_cleanup EXIT TERM INT
  22. function commachecker()
  23. {
  24. local prefix=1
  25. case "$1"
  26. in "--interval") prefix=2
  27. ;; "--per-thread") prefix=2
  28. ;; "--system-wide-no-aggr") prefix=2
  29. ;; "--per-core") prefix=3
  30. ;; "--per-socket") prefix=3
  31. ;; "--per-node") prefix=3
  32. ;; "--per-die") prefix=3
  33. ;; "--per-cache") prefix=3
  34. ;; "--per-cluster") prefix=3
  35. esac
  36. while read line
  37. do
  38. # Ignore initial "started on" comment.
  39. x=${line:0:1}
  40. [ "$x" = "#" ] && continue
  41. # Ignore initial blank line.
  42. [ "$line" = "" ] && continue
  43. # Ignore "Performance counter stats"
  44. x=${line:0:25}
  45. [ "$x" = "Performance counter stats" ] && continue
  46. # Ignore "seconds time elapsed" and break
  47. [[ "$line" == *"time elapsed"* ]] && break
  48. main_body=$(echo $line | cut -d' ' -f$prefix-)
  49. x=${main_body%#*}
  50. [ "$x" = "" ] && continue
  51. # Skip metrics without event name
  52. y=${main_body#*#}
  53. for i in "${!skip_metric[@]}"; do
  54. [[ "$y" == *"${skip_metric[$i]}"* ]] && break
  55. done
  56. [[ "$y" == *"${skip_metric[$i]}"* ]] && continue
  57. # Check default event
  58. for i in "${!event_name[@]}"; do
  59. [[ "$x" == *"${event_name[$i]}"* ]] && break
  60. done
  61. [[ ! "$x" == *"${event_name[$i]}"* ]] && {
  62. echo "Unknown event name in $line" 1>&2
  63. exit 1;
  64. }
  65. # Check event metric if it exists
  66. [[ ! "$main_body" == *"#"* ]] && continue
  67. [[ ! "$main_body" == *"${event_metric[$i]}"* ]] && {
  68. echo "wrong event metric. expected ${event_metric[$i]} in $line" 1>&2
  69. exit 1;
  70. }
  71. done < "${stat_output}"
  72. return 0
  73. }
  74. perf_cmd="-o ${stat_output}"
  75. skip_test=$(check_for_topology)
  76. check_no_args "STD" "$perf_cmd"
  77. check_system_wide "STD" "$perf_cmd"
  78. check_interval "STD" "$perf_cmd"
  79. check_per_thread "STD" "$perf_cmd"
  80. check_per_node "STD" "$perf_cmd"
  81. if [ $skip_test -ne 1 ]
  82. then
  83. check_system_wide_no_aggr "STD" "$perf_cmd"
  84. check_per_core "STD" "$perf_cmd"
  85. check_per_cache_instance "STD" "$perf_cmd"
  86. check_per_cluster "STD" "$perf_cmd"
  87. check_per_die "STD" "$perf_cmd"
  88. check_per_socket "STD" "$perf_cmd"
  89. else
  90. echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
  91. fi
  92. cleanup
  93. exit 0