From b41b1cd3b82a6fe7d601b2f09e26706a6c685f68 Mon Sep 17 00:00:00 2001 From: Sasha Goldshtein Date: Mon, 4 Sep 2017 09:19:53 -0400 Subject: [PATCH] funcslower: Make -p switch respect all the process' threads The -p switch used to set the `set_ftrace_pid` file, which is really a thread id from the user's perspective. As a result, only the main thread would be traced. Fix by enumerating the thread ids from /proc/ $pid/task and putting them all in `set_ftrace_pid` when asked. Signed-off-by: Sasha Goldshtein --- examples/funcslower_example.txt | 1 + kernel/funcslower | 27 ++++++++++++++++++++------- man/man8/funcslower.8 | 5 ++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/examples/funcslower_example.txt b/examples/funcslower_example.txt index 2a969f0..fb5a0d8 100644 --- a/examples/funcslower_example.txt +++ b/examples/funcslower_example.txt @@ -101,6 +101,7 @@ USAGE: funcslower [-aChHPt] [-p PID] [-d secs] funcstring latency_us -h # this usage message -H # include column headers -p PID # trace when this pid is on-CPU + -L TID # trace when this thread is on-CPU -P # show process names & PIDs -t # show timestamps eg, diff --git a/kernel/funcslower b/kernel/funcslower index 4fd986b..fd7fc3e 100755 --- a/kernel/funcslower +++ b/kernel/funcslower @@ -53,19 +53,20 @@ ### default variables tracing=/sys/kernel/debug/tracing flock=/var/tmp/.ftrace-lock -opt_duration=0; duration=; opt_pid=0; pid=; pidtext=; opt_headers=0 -opt_proc=0; opt_time=0; opt_cpu=0 +opt_duration=0; duration=; opt_pid=0; pid=; opt_tid=0; tid= +pidtext=; opt_headers=0; opt_proc=0; opt_time=0; opt_cpu=0 trap ':' INT QUIT TERM PIPE HUP # sends execution to end tracing section function usage { cat <<-END >&2 - USAGE: funcslower [-aChHPt] [-p PID] [-d secs] funcstring latency_us + USAGE: funcslower [-aChHPt] [-p PID] [-L TID] [-d secs] funcstring latency_us -a # all info (same as -HPt) -C # measure on-CPU time only -d seconds # trace duration, and use buffers -h # this usage message -H # include column headers -p PID # trace when this pid is on-CPU + -L TID # trace when this thread is on-CPU -P # show process names & PIDs -t # show timestamps eg, @@ -116,13 +117,14 @@ function edie { } ### process options -while getopts aCd:hHp:Pt opt +while getopts aCd:hHp:L:Pt opt do case $opt in a) opt_headers=1; opt_proc=1; opt_time=1 ;; C) opt_cpu=1; ;; d) opt_duration=1; duration=$OPTARG ;; p) opt_pid=1; pid=$OPTARG ;; + L) opt_tid=1; tid=$OPTARG ;; H) opt_headers=1; ;; P) opt_proc=1; ;; t) opt_time=1; ;; @@ -133,10 +135,12 @@ shift $(( $OPTIND - 1 )) ### option logic (( $# < 2 )) && usage +(( opt_pid && opt_tid )) && edie "ERROR: You can use -p or -L but not both." funcs="$1" shift thresh=$1 (( opt_pid )) && pidtext=" for PID $pid" +(( opt_tid )) && pidtext=" for TID $tid" printf "Tracing \"$funcs\"$pidtext slower than $thresh us" if (( opt_duration )); then echo " for $duration seconds..." @@ -175,9 +179,18 @@ if ! echo $thresh > tracing_thresh; then edie "ERROR: setting tracing_thresh to $thresh. Exiting." fi if (( opt_pid )); then - if ! echo $pid > set_ftrace_pid; then - edie "ERROR: setting -p $pid (PID exist?). Exiting." - fi + echo '' > set_ftrace_pid + # ftrace expects kernel pids, which are thread ids + for tid in /proc/$pid/task/*; do + if ! echo ${tid##*/} >> set_ftrace_pid; then + edie "ERROR: setting -p $pid (PID exist?). Exiting." + fi + done +fi +if (( opt_tid )); then + if ! echo $tid > set_ftrace_pid; then + edie "ERROR: setting -L $tid (TID exist?). Exiting." + fi fi if ! echo "$funcs" > set_ftrace_filter; then edie "ERROR: enabling \"$funcs\" filter. Function exist? Exiting." diff --git a/man/man8/funcslower.8 b/man/man8/funcslower.8 index b1a3a65..1c8f697 100644 --- a/man/man8/funcslower.8 +++ b/man/man8/funcslower.8 @@ -3,7 +3,7 @@ funcslower \- trace kernel functions slower than a threshold (microseconds). Uses Linux ftrace. .SH SYNOPSIS .B funcslower -[\-aChHPt] [\-p PID] [\-d secs] funcstring latency_us +[\-aChHPt] [\-p PID] [\-L TID] [\-d secs] funcstring latency_us .SH DESCRIPTION This uses the Linux ftrace function graph profiler to time kernel functions and filter them based on a latency threshold. Latency outliers can be studied @@ -49,6 +49,9 @@ Print column headers. \-p PID Only trace kernel functions when this process ID is on-CPU. .TP +\-L TID +Only trace kernel functions when this thread ID is on-CPU. +.TP \-P Show process names and process IDs with every line of output. .TP