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