record.sh 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #!/bin/bash
  2. # perf record tests
  3. # SPDX-License-Identifier: GPL-2.0
  4. set -e
  5. shelldir=$(dirname "$0")
  6. # shellcheck source=lib/waiting.sh
  7. . "${shelldir}"/lib/waiting.sh
  8. # shellcheck source=lib/perf_has_symbol.sh
  9. . "${shelldir}"/lib/perf_has_symbol.sh
  10. testsym="test_loop"
  11. skip_test_missing_symbol ${testsym}
  12. err=0
  13. perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
  14. testprog="perf test -w thloop"
  15. cpu_pmu_dir="/sys/bus/event_source/devices/cpu*"
  16. br_cntr_file="/caps/branch_counter_nr"
  17. br_cntr_output="branch stack counters"
  18. br_cntr_script_output="br_cntr: A"
  19. default_fd_limit=$(ulimit -Sn)
  20. # With option --threads=cpu the number of open file descriptors should be
  21. # equal to sum of: nmb_cpus * nmb_events (2+dummy),
  22. # nmb_threads for perf.data.n (equal to nmb_cpus) and
  23. # 2*nmb_cpus of pipes = 4*nmb_cpus (each pipe has 2 ends)
  24. # All together it needs 8*nmb_cpus file descriptors plus some are also used
  25. # outside of testing, thus raising the limit to 16*nmb_cpus
  26. min_fd_limit=$(($(getconf _NPROCESSORS_ONLN) * 16))
  27. cleanup() {
  28. rm -rf "${perfdata}"
  29. rm -rf "${perfdata}".old
  30. trap - EXIT TERM INT
  31. }
  32. trap_cleanup() {
  33. cleanup
  34. exit 1
  35. }
  36. trap trap_cleanup EXIT TERM INT
  37. test_per_thread() {
  38. echo "Basic --per-thread mode test"
  39. if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null
  40. then
  41. echo "Per-thread record [Skipped event not supported]"
  42. return
  43. fi
  44. if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null
  45. then
  46. echo "Per-thread record [Failed record]"
  47. err=1
  48. return
  49. fi
  50. if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
  51. then
  52. echo "Per-thread record [Failed missing output]"
  53. err=1
  54. return
  55. fi
  56. # run the test program in background (for 30 seconds)
  57. ${testprog} 30 &
  58. TESTPID=$!
  59. rm -f "${perfdata}"
  60. wait_for_threads ${TESTPID} 2
  61. perf record -p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev/null
  62. kill ${TESTPID}
  63. if [ ! -e "${perfdata}" ]
  64. then
  65. echo "Per-thread record [Failed record -p]"
  66. err=1
  67. return
  68. fi
  69. if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
  70. then
  71. echo "Per-thread record [Failed -p missing output]"
  72. err=1
  73. return
  74. fi
  75. echo "Basic --per-thread mode test [Success]"
  76. }
  77. test_register_capture() {
  78. echo "Register capture test"
  79. if ! perf list | grep -q 'br_inst_retired.near_call'
  80. then
  81. echo "Register capture test [Skipped missing event]"
  82. return
  83. fi
  84. if ! perf record --intr-regs=\? 2>&1 | grep -q 'available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15'
  85. then
  86. echo "Register capture test [Skipped missing registers]"
  87. return
  88. fi
  89. if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call \
  90. -c 1000 --per-thread ${testprog} 2> /dev/null \
  91. | perf script -F ip,sym,iregs -i - 2> /dev/null \
  92. | grep -q "DI:"
  93. then
  94. echo "Register capture test [Failed missing output]"
  95. err=1
  96. return
  97. fi
  98. echo "Register capture test [Success]"
  99. }
  100. test_system_wide() {
  101. echo "Basic --system-wide mode test"
  102. if ! perf record -aB --synth=no -o "${perfdata}" ${testprog} 2> /dev/null
  103. then
  104. echo "System-wide record [Skipped not supported]"
  105. return
  106. fi
  107. if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
  108. then
  109. echo "System-wide record [Failed missing output]"
  110. err=1
  111. return
  112. fi
  113. if ! perf record -aB --synth=no -e cpu-clock,cs --threads=cpu \
  114. -o "${perfdata}" ${testprog} 2> /dev/null
  115. then
  116. echo "System-wide record [Failed record --threads option]"
  117. err=1
  118. return
  119. fi
  120. if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
  121. then
  122. echo "System-wide record [Failed --threads missing output]"
  123. err=1
  124. return
  125. fi
  126. echo "Basic --system-wide mode test [Success]"
  127. }
  128. test_workload() {
  129. echo "Basic target workload test"
  130. if ! perf record -o "${perfdata}" ${testprog} 2> /dev/null
  131. then
  132. echo "Workload record [Failed record]"
  133. err=1
  134. return
  135. fi
  136. if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
  137. then
  138. echo "Workload record [Failed missing output]"
  139. err=1
  140. return
  141. fi
  142. if ! perf record -e cpu-clock,cs --threads=package \
  143. -o "${perfdata}" ${testprog} 2> /dev/null
  144. then
  145. echo "Workload record [Failed record --threads option]"
  146. err=1
  147. return
  148. fi
  149. if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
  150. then
  151. echo "Workload record [Failed --threads missing output]"
  152. err=1
  153. return
  154. fi
  155. echo "Basic target workload test [Success]"
  156. }
  157. test_branch_counter() {
  158. echo "Branch counter test"
  159. # Check if the branch counter feature is supported
  160. for dir in $cpu_pmu_dir
  161. do
  162. if [ ! -e "$dir$br_cntr_file" ]
  163. then
  164. echo "branch counter feature not supported on all core PMUs ($dir) [Skipped]"
  165. return
  166. fi
  167. done
  168. if ! perf record -o "${perfdata}" -e "{branches:p,instructions}" -j any,counter ${testprog} 2> /dev/null
  169. then
  170. echo "Branch counter record test [Failed record]"
  171. err=1
  172. return
  173. fi
  174. if ! perf report -i "${perfdata}" -D -q | grep -q "$br_cntr_output"
  175. then
  176. echo "Branch counter report test [Failed missing output]"
  177. err=1
  178. return
  179. fi
  180. if ! perf script -i "${perfdata}" -F +brstackinsn,+brcntr | grep -q "$br_cntr_script_output"
  181. then
  182. echo " Branch counter script test [Failed missing output]"
  183. err=1
  184. return
  185. fi
  186. echo "Branch counter test [Success]"
  187. }
  188. test_cgroup() {
  189. echo "Cgroup sampling test"
  190. if ! perf record -aB --synth=cgroup --all-cgroups -o "${perfdata}" ${testprog} 2> /dev/null
  191. then
  192. echo "Cgroup sampling [Skipped not supported]"
  193. return
  194. fi
  195. if ! perf report -i "${perfdata}" -D | grep -q "CGROUP"
  196. then
  197. echo "Cgroup sampling [Failed missing output]"
  198. err=1
  199. return
  200. fi
  201. if ! perf script -i "${perfdata}" -F cgroup | grep -q -v "unknown"
  202. then
  203. echo "Cgroup sampling [Failed cannot resolve cgroup names]"
  204. err=1
  205. return
  206. fi
  207. echo "Cgroup sampling test [Success]"
  208. }
  209. # raise the limit of file descriptors to minimum
  210. if [[ $default_fd_limit -lt $min_fd_limit ]]; then
  211. ulimit -Sn $min_fd_limit
  212. fi
  213. test_per_thread
  214. test_register_capture
  215. test_system_wide
  216. test_workload
  217. test_branch_counter
  218. test_cgroup
  219. # restore the default value
  220. ulimit -Sn $default_fd_limit
  221. cleanup
  222. exit $err