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