17e66ef00SMasami Hiramatsu#!/bin/sh 27e66ef00SMasami Hiramatsu# SPDX-License-Identifier: GPL-2.0-only 37e66ef00SMasami Hiramatsu 47e66ef00SMasami Hiramatsuusage() { 57e66ef00SMasami Hiramatsu echo "Ftrace boottime trace test tool" 65675fd4eSMasami Hiramatsu echo "Usage: $0 [--apply|--init] [--debug] BOOTCONFIG-FILE" 77e66ef00SMasami Hiramatsu echo " --apply: Test actual apply to tracefs (need sudo)" 85675fd4eSMasami Hiramatsu echo " --init: Initialize ftrace before applying (imply --apply)" 97e66ef00SMasami Hiramatsu exit 1 107e66ef00SMasami Hiramatsu} 117e66ef00SMasami Hiramatsu 127e66ef00SMasami Hiramatsu[ $# -eq 0 ] && usage 137e66ef00SMasami Hiramatsu 147e66ef00SMasami HiramatsuBCONF= 157e66ef00SMasami HiramatsuDEBUG= 167e66ef00SMasami HiramatsuAPPLY= 175675fd4eSMasami HiramatsuINIT= 187e66ef00SMasami Hiramatsuwhile [ x"$1" != x ]; do 197e66ef00SMasami Hiramatsu case "$1" in 207e66ef00SMasami Hiramatsu "--debug") 217e66ef00SMasami Hiramatsu DEBUG=$1;; 227e66ef00SMasami Hiramatsu "--apply") 237e66ef00SMasami Hiramatsu APPLY=$1;; 245675fd4eSMasami Hiramatsu "--init") 255675fd4eSMasami Hiramatsu APPLY=$1 265675fd4eSMasami Hiramatsu INIT=$1;; 277e66ef00SMasami Hiramatsu *) 287e66ef00SMasami Hiramatsu [ ! -f $1 ] && usage 297e66ef00SMasami Hiramatsu BCONF=$1;; 307e66ef00SMasami Hiramatsu esac 317e66ef00SMasami Hiramatsu shift 1 327e66ef00SMasami Hiramatsudone 337e66ef00SMasami Hiramatsu 347e66ef00SMasami Hiramatsuif [ x"$APPLY" != x ]; then 357e66ef00SMasami Hiramatsu if [ `id -u` -ne 0 ]; then 367e66ef00SMasami Hiramatsu echo "This must be run by root user. Try sudo." 1>&2 377e66ef00SMasami Hiramatsu exec sudo $0 $DEBUG $APPLY $BCONF 387e66ef00SMasami Hiramatsu fi 397e66ef00SMasami Hiramatsufi 407e66ef00SMasami Hiramatsu 417e66ef00SMasami Hiramatsurun_cmd() { # command 427e66ef00SMasami Hiramatsu echo "$*" 437e66ef00SMasami Hiramatsu if [ x"$APPLY" != x ]; then # apply command 447e66ef00SMasami Hiramatsu eval $* 457e66ef00SMasami Hiramatsu fi 467e66ef00SMasami Hiramatsu} 477e66ef00SMasami Hiramatsu 487e66ef00SMasami Hiramatsuif [ x"$DEBUG" != x ]; then 497e66ef00SMasami Hiramatsu set -x 507e66ef00SMasami Hiramatsufi 517e66ef00SMasami Hiramatsu 527e66ef00SMasami HiramatsuTRACEFS=`grep -m 1 -w tracefs /proc/mounts | cut -f 2 -d " "` 537e66ef00SMasami Hiramatsuif [ -z "$TRACEFS" ]; then 547e66ef00SMasami Hiramatsu if ! grep -wq debugfs /proc/mounts; then 557e66ef00SMasami Hiramatsu echo "Error: No tracefs/debugfs was mounted." 1>&2 567e66ef00SMasami Hiramatsu exit 1 577e66ef00SMasami Hiramatsu fi 587e66ef00SMasami Hiramatsu TRACEFS=`grep -m 1 -w debugfs /proc/mounts | cut -f 2 -d " "`/tracing 597e66ef00SMasami Hiramatsu if [ ! -d $TRACEFS ]; then 607e66ef00SMasami Hiramatsu echo "Error: ftrace is not enabled on this kernel." 1>&2 617e66ef00SMasami Hiramatsu exit 1 627e66ef00SMasami Hiramatsu fi 637e66ef00SMasami Hiramatsufi 647e66ef00SMasami Hiramatsu 655675fd4eSMasami Hiramatsuif [ x"$INIT" != x ]; then 665675fd4eSMasami Hiramatsu . `dirname $0`/ftrace.sh 675675fd4eSMasami Hiramatsu (cd $TRACEFS; initialize_ftrace) 685675fd4eSMasami Hiramatsufi 695675fd4eSMasami Hiramatsu 707e66ef00SMasami Hiramatsu. `dirname $0`/xbc.sh 717e66ef00SMasami Hiramatsu 727e66ef00SMasami Hiramatsu######## main ######### 737e66ef00SMasami Hiramatsuset -e 747e66ef00SMasami Hiramatsu 757e66ef00SMasami Hiramatsuxbc_init $BCONF 767e66ef00SMasami Hiramatsu 777e66ef00SMasami Hiramatsuset_value_of() { # key file 787e66ef00SMasami Hiramatsu if xbc_has_key $1; then 797e66ef00SMasami Hiramatsu val=`xbc_get_val $1 1` 807e66ef00SMasami Hiramatsu run_cmd "echo '$val' >> $2" 817e66ef00SMasami Hiramatsu fi 827e66ef00SMasami Hiramatsu} 837e66ef00SMasami Hiramatsu 847e66ef00SMasami Hiramatsuset_array_of() { # key file 857e66ef00SMasami Hiramatsu if xbc_has_key $1; then 867e66ef00SMasami Hiramatsu xbc_get_val $1 | while read line; do 877e66ef00SMasami Hiramatsu run_cmd "echo '$line' >> $2" 887e66ef00SMasami Hiramatsu done 897e66ef00SMasami Hiramatsu fi 907e66ef00SMasami Hiramatsu} 917e66ef00SMasami Hiramatsu 927e66ef00SMasami Hiramatsucompose_synth() { # event_name branch 937e66ef00SMasami Hiramatsu echo -n "$1 " 947e66ef00SMasami Hiramatsu xbc_get_val $2 | while read field; do echo -n "$field; "; done 957e66ef00SMasami Hiramatsu} 967e66ef00SMasami Hiramatsu 97*f134ebb2SMasami Hiramatsuprint_hist_array() { # prefix key 98*f134ebb2SMasami Hiramatsu __sep="=" 99*f134ebb2SMasami Hiramatsu if xbc_has_key ${1}.${2}; then 100*f134ebb2SMasami Hiramatsu echo -n ":$2" 101*f134ebb2SMasami Hiramatsu xbc_get_val ${1}.${2} | while read field; do 102*f134ebb2SMasami Hiramatsu echo -n "$__sep$field"; __sep="," 103*f134ebb2SMasami Hiramatsu done 104*f134ebb2SMasami Hiramatsu fi 105*f134ebb2SMasami Hiramatsu} 106*f134ebb2SMasami Hiramatsu 107*f134ebb2SMasami Hiramatsuprint_hist_action_array() { # prefix key 108*f134ebb2SMasami Hiramatsu __sep="(" 109*f134ebb2SMasami Hiramatsu echo -n ".$2" 110*f134ebb2SMasami Hiramatsu xbc_get_val ${1}.${2} | while read field; do 111*f134ebb2SMasami Hiramatsu echo -n "$__sep$field"; __sep="," 112*f134ebb2SMasami Hiramatsu done 113*f134ebb2SMasami Hiramatsu echo -n ")" 114*f134ebb2SMasami Hiramatsu} 115*f134ebb2SMasami Hiramatsu 116*f134ebb2SMasami Hiramatsuprint_hist_one_action() { # prefix handler param 117*f134ebb2SMasami Hiramatsu echo -n ":${2}("`xbc_get_val ${1}.${3}`")" 118*f134ebb2SMasami Hiramatsu if xbc_has_key "${1}.trace"; then 119*f134ebb2SMasami Hiramatsu print_hist_action_array ${1} "trace" 120*f134ebb2SMasami Hiramatsu elif xbc_has_key "${1}.save"; then 121*f134ebb2SMasami Hiramatsu print_hist_action_array ${1} "save" 122*f134ebb2SMasami Hiramatsu elif xbc_has_key "${1}.snapshot"; then 123*f134ebb2SMasami Hiramatsu echo -n ".snapshot()" 124*f134ebb2SMasami Hiramatsu fi 125*f134ebb2SMasami Hiramatsu} 126*f134ebb2SMasami Hiramatsu 127*f134ebb2SMasami Hiramatsuprint_hist_actions() { # prefix handler param 128*f134ebb2SMasami Hiramatsu for __hdr in `xbc_subkeys ${1}.${2} 1 ".[0-9]"`; do 129*f134ebb2SMasami Hiramatsu print_hist_one_action ${1}.${2}.$__hdr ${2} ${3} 130*f134ebb2SMasami Hiramatsu done 131*f134ebb2SMasami Hiramatsu if xbc_has_key ${1}.${2}.${3} ; then 132*f134ebb2SMasami Hiramatsu print_hist_one_action ${1}.${2} ${2} ${3} 133*f134ebb2SMasami Hiramatsu fi 134*f134ebb2SMasami Hiramatsu} 135*f134ebb2SMasami Hiramatsu 136*f134ebb2SMasami Hiramatsuprint_hist_var() { # prefix varname 137*f134ebb2SMasami Hiramatsu echo -n ":${2}="`xbc_get_val ${1}.var.${2} | tr -d [:space:]` 138*f134ebb2SMasami Hiramatsu} 139*f134ebb2SMasami Hiramatsu 140*f134ebb2SMasami Hiramatsuprint_one_histogram() { # prefix 141*f134ebb2SMasami Hiramatsu echo -n "hist" 142*f134ebb2SMasami Hiramatsu print_hist_array $1 "keys" 143*f134ebb2SMasami Hiramatsu print_hist_array $1 "values" 144*f134ebb2SMasami Hiramatsu print_hist_array $1 "sort" 145*f134ebb2SMasami Hiramatsu if xbc_has_key "${1}.size"; then 146*f134ebb2SMasami Hiramatsu echo -n ":size="`xbc_get_val ${1}.size` 147*f134ebb2SMasami Hiramatsu fi 148*f134ebb2SMasami Hiramatsu if xbc_has_key "${1}.name"; then 149*f134ebb2SMasami Hiramatsu echo -n ":name="`xbc_get_val ${1}.name` 150*f134ebb2SMasami Hiramatsu fi 151*f134ebb2SMasami Hiramatsu for __var in `xbc_subkeys "${1}.var" 1`; do 152*f134ebb2SMasami Hiramatsu print_hist_var ${1} ${__var} 153*f134ebb2SMasami Hiramatsu done 154*f134ebb2SMasami Hiramatsu if xbc_has_key "${1}.pause"; then 155*f134ebb2SMasami Hiramatsu echo -n ":pause" 156*f134ebb2SMasami Hiramatsu elif xbc_has_key "${1}.continue"; then 157*f134ebb2SMasami Hiramatsu echo -n ":continue" 158*f134ebb2SMasami Hiramatsu elif xbc_has_key "${1}.clear"; then 159*f134ebb2SMasami Hiramatsu echo -n ":clear" 160*f134ebb2SMasami Hiramatsu fi 161*f134ebb2SMasami Hiramatsu print_hist_actions ${1} "onmax" "var" 162*f134ebb2SMasami Hiramatsu print_hist_actions ${1} "onchange" "var" 163*f134ebb2SMasami Hiramatsu print_hist_actions ${1} "onmatch" "event" 164*f134ebb2SMasami Hiramatsu 165*f134ebb2SMasami Hiramatsu if xbc_has_key "${1}.filter"; then 166*f134ebb2SMasami Hiramatsu echo -n " if "`xbc_get_val ${1}.filter` 167*f134ebb2SMasami Hiramatsu fi 168*f134ebb2SMasami Hiramatsu} 169*f134ebb2SMasami Hiramatsu 170*f134ebb2SMasami Hiramatsusetup_one_histogram() { # prefix trigger-file 171*f134ebb2SMasami Hiramatsu run_cmd "echo '`print_one_histogram ${1}`' >> ${2}" 172*f134ebb2SMasami Hiramatsu} 173*f134ebb2SMasami Hiramatsu 174*f134ebb2SMasami Hiramatsusetup_histograms() { # prefix trigger-file 175*f134ebb2SMasami Hiramatsu for __hist in `xbc_subkeys ${1} 1 ".[0-9]"`; do 176*f134ebb2SMasami Hiramatsu setup_one_histogram ${1}.$__hist ${2} 177*f134ebb2SMasami Hiramatsu done 178*f134ebb2SMasami Hiramatsu if xbc_has_key ${1}.keys; then 179*f134ebb2SMasami Hiramatsu setup_one_histogram ${1} ${2} 180*f134ebb2SMasami Hiramatsu fi 181*f134ebb2SMasami Hiramatsu} 182*f134ebb2SMasami Hiramatsu 1837e66ef00SMasami Hiramatsusetup_event() { # prefix group event [instance] 1847e66ef00SMasami Hiramatsu branch=$1.$2.$3 1857e66ef00SMasami Hiramatsu if [ "$4" ]; then 1867e66ef00SMasami Hiramatsu eventdir="$TRACEFS/instances/$4/events/$2/$3" 1877e66ef00SMasami Hiramatsu else 1887e66ef00SMasami Hiramatsu eventdir="$TRACEFS/events/$2/$3" 1897e66ef00SMasami Hiramatsu fi 1901d8365a5SMasami Hiramatsu # group enable 1911d8365a5SMasami Hiramatsu if [ "$3" = "enable" ]; then 1921d8365a5SMasami Hiramatsu run_cmd "echo 1 > ${eventdir}" 1931d8365a5SMasami Hiramatsu return 1941d8365a5SMasami Hiramatsu fi 1951d8365a5SMasami Hiramatsu 1967e66ef00SMasami Hiramatsu case $2 in 1977e66ef00SMasami Hiramatsu kprobes) 1987e66ef00SMasami Hiramatsu xbc_get_val ${branch}.probes | while read line; do 1997e66ef00SMasami Hiramatsu run_cmd "echo 'p:kprobes/$3 $line' >> $TRACEFS/kprobe_events" 2007e66ef00SMasami Hiramatsu done 2017e66ef00SMasami Hiramatsu ;; 2027e66ef00SMasami Hiramatsu synthetic) 2037e66ef00SMasami Hiramatsu run_cmd "echo '`compose_synth $3 ${branch}.fields`' >> $TRACEFS/synthetic_events" 2047e66ef00SMasami Hiramatsu ;; 2057e66ef00SMasami Hiramatsu esac 2067e66ef00SMasami Hiramatsu 2077e66ef00SMasami Hiramatsu set_value_of ${branch}.filter ${eventdir}/filter 2087e66ef00SMasami Hiramatsu set_array_of ${branch}.actions ${eventdir}/trigger 2097e66ef00SMasami Hiramatsu 210*f134ebb2SMasami Hiramatsu setup_histograms ${branch}.hist ${eventdir}/trigger 211*f134ebb2SMasami Hiramatsu 2127e66ef00SMasami Hiramatsu if xbc_has_key ${branch}.enable; then 2137e66ef00SMasami Hiramatsu run_cmd "echo 1 > ${eventdir}/enable" 2147e66ef00SMasami Hiramatsu fi 2157e66ef00SMasami Hiramatsu} 2167e66ef00SMasami Hiramatsu 2177e66ef00SMasami Hiramatsusetup_events() { # prefix("ftrace" or "ftrace.instance.INSTANCE") [instance] 2187e66ef00SMasami Hiramatsu prefix="${1}.event" 2197e66ef00SMasami Hiramatsu if xbc_has_branch ${1}.event; then 2207e66ef00SMasami Hiramatsu for grpev in `xbc_subkeys ${1}.event 2`; do 2217e66ef00SMasami Hiramatsu setup_event $prefix ${grpev%.*} ${grpev#*.} $2 2227e66ef00SMasami Hiramatsu done 2237e66ef00SMasami Hiramatsu fi 2241d8365a5SMasami Hiramatsu if xbc_has_branch ${1}.event.enable; then 2251d8365a5SMasami Hiramatsu if [ "$2" ]; then 2261d8365a5SMasami Hiramatsu run_cmd "echo 1 > $TRACEFS/instances/$2/events/enable" 2271d8365a5SMasami Hiramatsu else 2281d8365a5SMasami Hiramatsu run_cmd "echo 1 > $TRACEFS/events/enable" 2291d8365a5SMasami Hiramatsu fi 2301d8365a5SMasami Hiramatsu fi 2317e66ef00SMasami Hiramatsu} 2327e66ef00SMasami Hiramatsu 2337e66ef00SMasami Hiramatsusize2kb() { # size[KB|MB] 2347e66ef00SMasami Hiramatsu case $1 in 2357e66ef00SMasami Hiramatsu *KB) 2367e66ef00SMasami Hiramatsu echo ${1%KB};; 2377e66ef00SMasami Hiramatsu *MB) 2387e66ef00SMasami Hiramatsu expr ${1%MB} \* 1024;; 2397e66ef00SMasami Hiramatsu *) 2407e66ef00SMasami Hiramatsu expr $1 / 1024 ;; 2417e66ef00SMasami Hiramatsu esac 2427e66ef00SMasami Hiramatsu} 2437e66ef00SMasami Hiramatsu 2447e66ef00SMasami Hiramatsusetup_instance() { # [instance] 2457e66ef00SMasami Hiramatsu if [ "$1" ]; then 2467e66ef00SMasami Hiramatsu instance="ftrace.instance.${1}" 2477e66ef00SMasami Hiramatsu instancedir=$TRACEFS/instances/$1 2487e66ef00SMasami Hiramatsu else 2497e66ef00SMasami Hiramatsu instance="ftrace" 2507e66ef00SMasami Hiramatsu instancedir=$TRACEFS 2517e66ef00SMasami Hiramatsu fi 2527e66ef00SMasami Hiramatsu 2537e66ef00SMasami Hiramatsu set_array_of ${instance}.options ${instancedir}/trace_options 2547e66ef00SMasami Hiramatsu set_value_of ${instance}.trace_clock ${instancedir}/trace_clock 2557e66ef00SMasami Hiramatsu set_value_of ${instance}.cpumask ${instancedir}/tracing_cpumask 25655ed4560SMasami Hiramatsu set_value_of ${instance}.tracing_on ${instancedir}/tracing_on 2577e66ef00SMasami Hiramatsu set_value_of ${instance}.tracer ${instancedir}/current_tracer 2587e66ef00SMasami Hiramatsu set_array_of ${instance}.ftrace.filters \ 2597e66ef00SMasami Hiramatsu ${instancedir}/set_ftrace_filter 2607e66ef00SMasami Hiramatsu set_array_of ${instance}.ftrace.notrace \ 2617e66ef00SMasami Hiramatsu ${instancedir}/set_ftrace_notrace 2627e66ef00SMasami Hiramatsu 2637e66ef00SMasami Hiramatsu if xbc_has_key ${instance}.alloc_snapshot; then 2647e66ef00SMasami Hiramatsu run_cmd "echo 1 > ${instancedir}/snapshot" 2657e66ef00SMasami Hiramatsu fi 2667e66ef00SMasami Hiramatsu 2677e66ef00SMasami Hiramatsu if xbc_has_key ${instance}.buffer_size; then 2687e66ef00SMasami Hiramatsu size=`xbc_get_val ${instance}.buffer_size 1` 2697e66ef00SMasami Hiramatsu size=`eval size2kb $size` 2707e66ef00SMasami Hiramatsu run_cmd "echo $size >> ${instancedir}/buffer_size_kb" 2717e66ef00SMasami Hiramatsu fi 2727e66ef00SMasami Hiramatsu 2737e66ef00SMasami Hiramatsu setup_events ${instance} $1 2747e66ef00SMasami Hiramatsu set_array_of ${instance}.events ${instancedir}/set_event 2757e66ef00SMasami Hiramatsu} 2767e66ef00SMasami Hiramatsu 2777e66ef00SMasami Hiramatsu# ftrace global configs (kernel.*) 2787e66ef00SMasami Hiramatsuif xbc_has_key "kernel.dump_on_oops"; then 2797e66ef00SMasami Hiramatsu dump_mode=`xbc_get_val "kernel.dump_on_oops" 1` 2807e66ef00SMasami Hiramatsu [ "$dump_mode" ] && dump_mode=`eval echo $dump_mode` || dump_mode=1 2817e66ef00SMasami Hiramatsu run_cmd "echo \"$dump_mode\" > /proc/sys/kernel/ftrace_dump_on_oops" 2827e66ef00SMasami Hiramatsufi 2837e66ef00SMasami Hiramatsu 2847e66ef00SMasami Hiramatsuset_value_of kernel.fgraph_max_depth $TRACEFS/max_graph_depth 2857e66ef00SMasami Hiramatsuset_array_of kernel.fgraph_filters $TRACEFS/set_graph_function 2867e66ef00SMasami Hiramatsuset_array_of kernel.fgraph_notraces $TRACEFS/set_graph_notrace 2877e66ef00SMasami Hiramatsu 2887e66ef00SMasami Hiramatsu# Per-instance/per-event configs 2897e66ef00SMasami Hiramatsuif ! xbc_has_branch "ftrace" ; then 2907e66ef00SMasami Hiramatsu exit 0 2917e66ef00SMasami Hiramatsufi 2927e66ef00SMasami Hiramatsu 2937e66ef00SMasami Hiramatsusetup_instance # root instance 2947e66ef00SMasami Hiramatsu 2957e66ef00SMasami Hiramatsuif xbc_has_branch "ftrace.instance"; then 2967e66ef00SMasami Hiramatsu for i in `xbc_subkeys "ftrace.instance" 1`; do 2977e66ef00SMasami Hiramatsu run_cmd "mkdir -p $TRACEFS/instances/$i" 2987e66ef00SMasami Hiramatsu setup_instance $i 2997e66ef00SMasami Hiramatsu done 3007e66ef00SMasami Hiramatsufi 3017e66ef00SMasami Hiramatsu 302