bconf2ftrace.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #!/bin/sh
  2. # SPDX-License-Identifier: GPL-2.0-only
  3. usage() {
  4. echo "Ftrace boottime trace test tool"
  5. echo "Usage: $0 [--apply|--init] [--debug] BOOTCONFIG-FILE"
  6. echo " --apply: Test actual apply to tracefs (need sudo)"
  7. echo " --init: Initialize ftrace before applying (imply --apply)"
  8. exit 1
  9. }
  10. [ $# -eq 0 ] && usage
  11. BCONF=
  12. DEBUG=
  13. APPLY=
  14. INIT=
  15. while [ x"$1" != x ]; do
  16. case "$1" in
  17. "--debug")
  18. DEBUG=$1;;
  19. "--apply")
  20. APPLY=$1;;
  21. "--init")
  22. APPLY=$1
  23. INIT=$1;;
  24. *)
  25. [ ! -f $1 ] && usage
  26. BCONF=$1;;
  27. esac
  28. shift 1
  29. done
  30. if [ x"$APPLY" != x ]; then
  31. if [ `id -u` -ne 0 ]; then
  32. echo "This must be run by root user. Try sudo." 1>&2
  33. exec sudo $0 $DEBUG $APPLY $BCONF
  34. fi
  35. fi
  36. run_cmd() { # command
  37. echo "$*"
  38. if [ x"$APPLY" != x ]; then # apply command
  39. eval $*
  40. fi
  41. }
  42. if [ x"$DEBUG" != x ]; then
  43. set -x
  44. fi
  45. TRACEFS=`grep -m 1 -w tracefs /proc/mounts | cut -f 2 -d " "`
  46. if [ -z "$TRACEFS" ]; then
  47. if ! grep -wq debugfs /proc/mounts; then
  48. echo "Error: No tracefs/debugfs was mounted." 1>&2
  49. exit 1
  50. fi
  51. TRACEFS=`grep -m 1 -w debugfs /proc/mounts | cut -f 2 -d " "`/tracing
  52. if [ ! -d $TRACEFS ]; then
  53. echo "Error: ftrace is not enabled on this kernel." 1>&2
  54. exit 1
  55. fi
  56. fi
  57. if [ x"$INIT" != x ]; then
  58. . `dirname $0`/ftrace.sh
  59. (cd $TRACEFS; initialize_ftrace)
  60. fi
  61. . `dirname $0`/xbc.sh
  62. ######## main #########
  63. set -e
  64. xbc_init $BCONF
  65. set_value_of() { # key file
  66. if xbc_has_key $1; then
  67. val=`xbc_get_val $1 1`
  68. run_cmd "echo '$val' >> $2"
  69. fi
  70. }
  71. set_array_of() { # key file
  72. if xbc_has_key $1; then
  73. xbc_get_val $1 | while read line; do
  74. run_cmd "echo '$line' >> $2"
  75. done
  76. fi
  77. }
  78. compose_synth() { # event_name branch
  79. echo -n "$1 "
  80. xbc_get_val $2 | while read field; do echo -n "$field; "; done
  81. }
  82. print_hist_array() { # prefix key
  83. __sep="="
  84. if xbc_has_key ${1}.${2}; then
  85. echo -n ":$2"
  86. xbc_get_val ${1}.${2} | while read field; do
  87. echo -n "$__sep$field"; __sep=","
  88. done
  89. fi
  90. }
  91. print_hist_action_array() { # prefix key
  92. __sep="("
  93. echo -n ".$2"
  94. xbc_get_val ${1}.${2} | while read field; do
  95. echo -n "$__sep$field"; __sep=","
  96. done
  97. echo -n ")"
  98. }
  99. print_hist_one_action() { # prefix handler param
  100. echo -n ":${2}("`xbc_get_val ${1}.${3}`")"
  101. if xbc_has_key "${1}.trace"; then
  102. print_hist_action_array ${1} "trace"
  103. elif xbc_has_key "${1}.save"; then
  104. print_hist_action_array ${1} "save"
  105. elif xbc_has_key "${1}.snapshot"; then
  106. echo -n ".snapshot()"
  107. fi
  108. }
  109. print_hist_actions() { # prefix handler param
  110. for __hdr in `xbc_subkeys ${1}.${2} 1 ".[0-9]"`; do
  111. print_hist_one_action ${1}.${2}.$__hdr ${2} ${3}
  112. done
  113. if xbc_has_key ${1}.${2}.${3} ; then
  114. print_hist_one_action ${1}.${2} ${2} ${3}
  115. fi
  116. }
  117. print_hist_var() { # prefix varname
  118. echo -n ":${2}="`xbc_get_val ${1}.var.${2} | tr -d [:space:]`
  119. }
  120. print_one_histogram() { # prefix
  121. echo -n "hist"
  122. print_hist_array $1 "keys"
  123. print_hist_array $1 "values"
  124. print_hist_array $1 "sort"
  125. if xbc_has_key "${1}.size"; then
  126. echo -n ":size="`xbc_get_val ${1}.size`
  127. fi
  128. if xbc_has_key "${1}.name"; then
  129. echo -n ":name="`xbc_get_val ${1}.name`
  130. fi
  131. for __var in `xbc_subkeys "${1}.var" 1`; do
  132. print_hist_var ${1} ${__var}
  133. done
  134. if xbc_has_key "${1}.pause"; then
  135. echo -n ":pause"
  136. elif xbc_has_key "${1}.continue"; then
  137. echo -n ":continue"
  138. elif xbc_has_key "${1}.clear"; then
  139. echo -n ":clear"
  140. fi
  141. print_hist_actions ${1} "onmax" "var"
  142. print_hist_actions ${1} "onchange" "var"
  143. print_hist_actions ${1} "onmatch" "event"
  144. if xbc_has_key "${1}.filter"; then
  145. echo -n " if "`xbc_get_val ${1}.filter`
  146. fi
  147. }
  148. setup_one_histogram() { # prefix trigger-file
  149. run_cmd "echo '`print_one_histogram ${1}`' >> ${2}"
  150. }
  151. setup_histograms() { # prefix trigger-file
  152. for __hist in `xbc_subkeys ${1} 1 ".[0-9]"`; do
  153. setup_one_histogram ${1}.$__hist ${2}
  154. done
  155. if xbc_has_key ${1}.keys; then
  156. setup_one_histogram ${1} ${2}
  157. fi
  158. }
  159. setup_event() { # prefix group event [instance]
  160. branch=$1.$2.$3
  161. if [ "$4" ]; then
  162. eventdir="$TRACEFS/instances/$4/events/$2/$3"
  163. else
  164. eventdir="$TRACEFS/events/$2/$3"
  165. fi
  166. # group enable
  167. if [ "$3" = "enable" ]; then
  168. run_cmd "echo 1 > ${eventdir}"
  169. return
  170. fi
  171. case $2 in
  172. kprobes)
  173. xbc_get_val ${branch}.probes | while read line; do
  174. run_cmd "echo 'p:kprobes/$3 $line' >> $TRACEFS/kprobe_events"
  175. done
  176. ;;
  177. synthetic)
  178. run_cmd "echo '`compose_synth $3 ${branch}.fields`' >> $TRACEFS/synthetic_events"
  179. ;;
  180. esac
  181. set_value_of ${branch}.filter ${eventdir}/filter
  182. set_array_of ${branch}.actions ${eventdir}/trigger
  183. setup_histograms ${branch}.hist ${eventdir}/trigger
  184. if xbc_has_key ${branch}.enable; then
  185. run_cmd "echo 1 > ${eventdir}/enable"
  186. fi
  187. }
  188. setup_events() { # prefix("ftrace" or "ftrace.instance.INSTANCE") [instance]
  189. prefix="${1}.event"
  190. if xbc_has_branch ${1}.event; then
  191. for grpev in `xbc_subkeys ${1}.event 2`; do
  192. setup_event $prefix ${grpev%.*} ${grpev#*.} $2
  193. done
  194. fi
  195. if xbc_has_branch ${1}.event.enable; then
  196. if [ "$2" ]; then
  197. run_cmd "echo 1 > $TRACEFS/instances/$2/events/enable"
  198. else
  199. run_cmd "echo 1 > $TRACEFS/events/enable"
  200. fi
  201. fi
  202. }
  203. size2kb() { # size[KB|MB]
  204. case $1 in
  205. *KB)
  206. echo ${1%KB};;
  207. *MB)
  208. expr ${1%MB} \* 1024;;
  209. *)
  210. expr $1 / 1024 ;;
  211. esac
  212. }
  213. setup_instance() { # [instance]
  214. if [ "$1" ]; then
  215. instance="ftrace.instance.${1}"
  216. instancedir=$TRACEFS/instances/$1
  217. else
  218. instance="ftrace"
  219. instancedir=$TRACEFS
  220. fi
  221. set_array_of ${instance}.options ${instancedir}/trace_options
  222. set_value_of ${instance}.trace_clock ${instancedir}/trace_clock
  223. set_value_of ${instance}.cpumask ${instancedir}/tracing_cpumask
  224. set_value_of ${instance}.tracing_on ${instancedir}/tracing_on
  225. set_value_of ${instance}.tracer ${instancedir}/current_tracer
  226. set_array_of ${instance}.ftrace.filters \
  227. ${instancedir}/set_ftrace_filter
  228. set_array_of ${instance}.ftrace.notrace \
  229. ${instancedir}/set_ftrace_notrace
  230. if xbc_has_key ${instance}.alloc_snapshot; then
  231. run_cmd "echo 1 > ${instancedir}/snapshot"
  232. fi
  233. if xbc_has_key ${instance}.buffer_size; then
  234. size=`xbc_get_val ${instance}.buffer_size 1`
  235. size=`eval size2kb $size`
  236. run_cmd "echo $size >> ${instancedir}/buffer_size_kb"
  237. fi
  238. setup_events ${instance} $1
  239. set_array_of ${instance}.events ${instancedir}/set_event
  240. }
  241. # ftrace global configs (kernel.*)
  242. if xbc_has_key "kernel.dump_on_oops"; then
  243. dump_mode=`xbc_get_val "kernel.dump_on_oops" 1`
  244. [ "$dump_mode" ] && dump_mode=`eval echo $dump_mode` || dump_mode=1
  245. run_cmd "echo \"$dump_mode\" > /proc/sys/kernel/ftrace_dump_on_oops"
  246. fi
  247. set_value_of kernel.fgraph_max_depth $TRACEFS/max_graph_depth
  248. set_array_of kernel.fgraph_filters $TRACEFS/set_graph_function
  249. set_array_of kernel.fgraph_notraces $TRACEFS/set_graph_notrace
  250. # Per-instance/per-event configs
  251. if ! xbc_has_branch "ftrace" ; then
  252. exit 0
  253. fi
  254. setup_instance # root instance
  255. if xbc_has_branch "ftrace.instance"; then
  256. for i in `xbc_subkeys "ftrace.instance" 1`; do
  257. run_cmd "mkdir -p $TRACEFS/instances/$i"
  258. setup_instance $i
  259. done
  260. fi