perf tools: Pass build_id object to dso__build_id_equal()
[linux-2.6-microblaze.git] / tools / perf / perf-with-kcore.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0-only
3 # perf-with-kcore: use perf with a copy of kcore
4 # Copyright (c) 2014, Intel Corporation.
5 #
6
7 set -e
8
9 usage()
10 {
11         echo "Usage: perf-with-kcore <perf sub-command> <perf.data directory> [<sub-command options> [ -- <workload>]]" >&2
12         echo "       <perf sub-command> can be record, script, report or inject" >&2
13         echo "   or: perf-with-kcore fix_buildid_cache_permissions" >&2
14         exit 1
15 }
16
17 find_perf()
18 {
19         if [ -n "$PERF" ] ; then
20                 return
21         fi
22         PERF=`which perf || true`
23         if [ -z "$PERF" ] ; then
24                 echo "Failed to find perf" >&2
25                 exit 1
26         fi
27         if [ ! -x "$PERF" ] ; then
28                 echo "Failed to find perf" >&2
29                 exit 1
30         fi
31         echo "Using $PERF"
32         "$PERF" version
33 }
34
35 copy_kcore()
36 {
37         echo "Copying kcore"
38
39         if [ $EUID -eq 0 ] ; then
40                 SUDO=""
41         else
42                 SUDO="sudo"
43         fi
44
45         rm -f perf.data.junk
46         ("$PERF" record -o perf.data.junk "${PERF_OPTIONS[@]}" -- sleep 60) >/dev/null 2>/dev/null &
47         PERF_PID=$!
48
49         # Need to make sure that perf has started
50         sleep 1
51
52         KCORE=$(($SUDO "$PERF" buildid-cache -v -f -k /proc/kcore >/dev/null) 2>&1)
53         case "$KCORE" in
54         "kcore added to build-id cache directory "*)
55                 KCORE_DIR=${KCORE#"kcore added to build-id cache directory "}
56         ;;
57         *)
58                 kill $PERF_PID
59                 wait >/dev/null 2>/dev/null || true
60                 rm perf.data.junk
61                 echo "$KCORE"
62                 echo "Failed to find kcore" >&2
63                 exit 1
64         ;;
65         esac
66
67         kill $PERF_PID
68         wait >/dev/null 2>/dev/null || true
69         rm perf.data.junk
70
71         $SUDO cp -a "$KCORE_DIR" "$(pwd)/$PERF_DATA_DIR"
72         $SUDO rm -f "$KCORE_DIR/kcore"
73         $SUDO rm -f "$KCORE_DIR/kallsyms"
74         $SUDO rm -f "$KCORE_DIR/modules"
75         $SUDO rmdir "$KCORE_DIR"
76
77         KCORE_DIR_BASENAME=$(basename "$KCORE_DIR")
78         KCORE_DIR="$(pwd)/$PERF_DATA_DIR/$KCORE_DIR_BASENAME"
79
80         $SUDO chown $UID "$KCORE_DIR"
81         $SUDO chown $UID "$KCORE_DIR/kcore"
82         $SUDO chown $UID "$KCORE_DIR/kallsyms"
83         $SUDO chown $UID "$KCORE_DIR/modules"
84
85         $SUDO chgrp $GROUPS "$KCORE_DIR"
86         $SUDO chgrp $GROUPS "$KCORE_DIR/kcore"
87         $SUDO chgrp $GROUPS "$KCORE_DIR/kallsyms"
88         $SUDO chgrp $GROUPS "$KCORE_DIR/modules"
89
90         ln -s "$KCORE_DIR_BASENAME" "$PERF_DATA_DIR/kcore_dir"
91 }
92
93 fix_buildid_cache_permissions()
94 {
95         if [ $EUID -ne 0 ] ; then
96                 echo "This script must be run as root via sudo " >&2
97                 exit 1
98         fi
99
100         if [ -z "$SUDO_USER" ] ; then
101                 echo "This script must be run via sudo" >&2
102                 exit 1
103         fi
104
105         USER_HOME=$(bash <<< "echo ~$SUDO_USER")
106
107         echo "Fixing buildid cache permissions"
108
109         find "$USER_HOME/.debug" -xdev -type d          ! -user "$SUDO_USER" -ls -exec chown    "$SUDO_USER" \{\} \;
110         find "$USER_HOME/.debug" -xdev -type f -links 1 ! -user "$SUDO_USER" -ls -exec chown    "$SUDO_USER" \{\} \;
111         find "$USER_HOME/.debug" -xdev -type l          ! -user "$SUDO_USER" -ls -exec chown -h "$SUDO_USER" \{\} \;
112
113         if [ -n "$SUDO_GID" ] ; then
114                 find "$USER_HOME/.debug" -xdev -type d          ! -group "$SUDO_GID" -ls -exec chgrp    "$SUDO_GID" \{\} \;
115                 find "$USER_HOME/.debug" -xdev -type f -links 1 ! -group "$SUDO_GID" -ls -exec chgrp    "$SUDO_GID" \{\} \;
116                 find "$USER_HOME/.debug" -xdev -type l          ! -group "$SUDO_GID" -ls -exec chgrp -h "$SUDO_GID" \{\} \;
117         fi
118
119         echo "Done"
120 }
121
122 check_buildid_cache_permissions()
123 {
124         if [ $EUID -eq 0 ] ; then
125                 return
126         fi
127
128         PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type d          ! -user "$USER" -print -quit)
129         PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type f -links 1 ! -user "$USER" -print -quit)
130         PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type l          ! -user "$USER" -print -quit)
131
132         PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type d          ! -group "$GROUPS" -print -quit)
133         PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type f -links 1 ! -group "$GROUPS" -print -quit)
134         PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type l          ! -group "$GROUPS" -print -quit)
135
136         if [ -n "$PERMISSIONS_OK" ] ; then
137                 echo "*** WARNING *** buildid cache permissions may need fixing" >&2
138         fi
139 }
140
141 record()
142 {
143         echo "Recording"
144
145         if [ $EUID -ne 0 ] ; then
146
147                 if [ "$(cat /proc/sys/kernel/kptr_restrict)" -ne 0 ] ; then
148                         echo "*** WARNING *** /proc/sys/kernel/kptr_restrict prevents access to kernel addresses" >&2
149                 fi
150
151                 if echo "${PERF_OPTIONS[@]}" | grep -q ' -a \|^-a \| -a$\|^-a$\| --all-cpus \|^--all-cpus \| --all-cpus$\|^--all-cpus$' ; then
152                         echo "*** WARNING *** system-wide tracing without root access will not be able to read all necessary information from /proc" >&2
153                 fi
154
155                 if echo "${PERF_OPTIONS[@]}" | grep -q 'intel_pt\|intel_bts\| -I\|^-I' ; then
156                         if [ "$(cat /proc/sys/kernel/perf_event_paranoid)" -gt -1 ] ; then
157                                 echo "*** WARNING *** /proc/sys/kernel/perf_event_paranoid restricts buffer size and tracepoint (sched_switch) use" >&2
158                         fi
159
160                         if echo "${PERF_OPTIONS[@]}" | grep -q ' --per-thread \|^--per-thread \| --per-thread$\|^--per-thread$' ; then
161                                 true
162                         elif echo "${PERF_OPTIONS[@]}" | grep -q ' -t \|^-t \| -t$\|^-t$' ; then
163                                 true
164                         elif [ ! -r /sys/kernel/debug -o ! -x /sys/kernel/debug ] ; then
165                                 echo "*** WARNING *** /sys/kernel/debug permissions prevent tracepoint (sched_switch) use" >&2
166                         fi
167                 fi
168         fi
169
170         if [ -z "$1" ] ; then
171                 echo "Workload is required for recording" >&2
172                 usage
173         fi
174
175         if [ -e "$PERF_DATA_DIR" ] ; then
176                 echo "'$PERF_DATA_DIR' exists" >&2
177                 exit 1
178         fi
179
180         find_perf
181
182         mkdir "$PERF_DATA_DIR"
183
184         echo "$PERF record -o $PERF_DATA_DIR/perf.data ${PERF_OPTIONS[@]} -- $@"
185         "$PERF" record -o "$PERF_DATA_DIR/perf.data" "${PERF_OPTIONS[@]}" -- "$@" || true
186
187         if rmdir "$PERF_DATA_DIR" > /dev/null 2>/dev/null ; then
188                 exit 1
189         fi
190
191         copy_kcore
192
193         echo "Done"
194 }
195
196 subcommand()
197 {
198         find_perf
199         check_buildid_cache_permissions
200         echo "$PERF $PERF_SUB_COMMAND -i $PERF_DATA_DIR/perf.data --kallsyms=$PERF_DATA_DIR/kcore_dir/kallsyms $@"
201         "$PERF" $PERF_SUB_COMMAND -i "$PERF_DATA_DIR/perf.data" "--kallsyms=$PERF_DATA_DIR/kcore_dir/kallsyms" "$@"
202 }
203
204 if [ "$1" = "fix_buildid_cache_permissions" ] ; then
205         fix_buildid_cache_permissions
206         exit 0
207 fi
208
209 PERF_SUB_COMMAND=$1
210 PERF_DATA_DIR=$2
211 shift || true
212 shift || true
213
214 if [ -z "$PERF_SUB_COMMAND" ] ; then
215         usage
216 fi
217
218 if [ -z "$PERF_DATA_DIR" ] ; then
219         usage
220 fi
221
222 case "$PERF_SUB_COMMAND" in
223 "record")
224         while [ "$1" != "--" ] ; do
225                 PERF_OPTIONS+=("$1")
226                 shift || break
227         done
228         if [ "$1" != "--" ] ; then
229                 echo "Options and workload are required for recording" >&2
230                 usage
231         fi
232         shift
233         record "$@"
234 ;;
235 "script")
236         subcommand "$@"
237 ;;
238 "report")
239         subcommand "$@"
240 ;;
241 "inject")
242         subcommand "$@"
243 ;;
244 *)
245         usage
246 ;;
247 esac