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