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