blob: 8c64af9a25445567306f81bb54e5f72d147023eb [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001#!/bin/sh
2#
3# opcontrol is a script to control OProfile
4# opcontrol --help and opcontrol --list-events have info
5#
6# Copyright 2002
7# Read the file COPYING
8#
9# Authors: John Levon, Philippe Elie, Will Cohen, Jens Wilke, Daniel Hansel
10#
11# Copyright IBM Corporation 2007
12#
13# NOTE: This script should be as shell independent as possible
14
15SYSCTL=do_sysctl
16
17# A replacement function for the sysctl (procps package) utility which is
18# missing on some distribution (e.g. slack 7.0).
19# Handles only the -w option of sysctl.
20do_sysctl()
21{
22 if test "$1" != "-w"; then
23 echo "$0 unknown sysctl option" >&2
24 exit 1
25 fi
26
27 shift
28
29 arg=`echo $1 | awk -F= '{print $1}'`
30 val=`echo $1 | awk -F= '{print $2}'`
31
32 dev_name=`echo $arg | tr . /`
33
34 if test ! -f /proc/sys/$dev_name; then
35 echo "/proc/sys/$dev_name does not exist or is not a regular file" >&2
36 exit 1
37 fi
38 echo $val > /proc/sys/$dev_name
39}
40
41
42# check value is set
43error_if_empty()
44{
45 if test -z "$2"; then
46 echo "No value given for option $1" >&2
47 do_help
48 exit 1
49 fi
50}
51
Jeff Brown7a33c862011-02-02 14:00:44 -080052# guess_number_base() checks if string is a valid octal(8), hexidecimal(16),
53# or decimal number(10). The value is returned in $?. Returns 0, if string
54# isn't a octal, hexidecimal, or decimal number.
55guess_number_base()
56{
57 if [[ "$1" =~ ^0[0-7]*$ ]] ; then
58 return 8;
59 elif [[ "$1" =~ ^0x[0-9a-fA-F]+$ ]] ; then
60 return 16;
61 elif [[ "$1" =~ ^[1-9][0-9]*$ ]] ; then
62 return 10;
63 else
64 return 0;
65 fi
66}
67
68# check value is a valid number
69error_if_not_number()
70{
71 guess_number_base $2
72 if test "$?" -eq 0 ; then
73 echo "Argument for $1, $2, is not a valid number." >&2
74 exit 1
75 fi
76}
Mike Dodd8cfa7022010-11-17 11:12:26 -080077
78# rm_device arguments $1=file_name
79rm_device()
80{
81 if test -c "$1"; then
82 vecho "Removing $1"
83 rm "$1"
84 fi
85}
86
87
88# create_device arguments $1=file_name $2=MAJOR_NR $3=MINOR_NR
89create_device()
90{
91 vecho "Doing mknod $1"
92 mknod "$1" c $2 $3
93 if test "$?" != "0"; then
94 echo "Couldn't mknod $1" >&2
95 exit 1
96 fi
97 chmod 700 "$1"
98}
99
100
101move_and_remove()
102{
103 if test -e $1; then
104 mv $1 $SAMPLES_DIR/.tmp_reset.$$
105 rm -rf $SAMPLES_DIR/.tmp_reset.$$
106 fi
107}
108
109
110# verbose echo
111vecho()
112{
113 if test -n "$VERBOSE"; then
114 echo $@
115 fi
116}
117
118
119is_tool_available()
120{
121 if which $1 &>/dev/null; then
122 if test -x `which $1`; then
123 return 1
124 fi
125 fi
126
127 return 0
128}
129
130
131# print help message
132do_help()
133{
134 cat >&2 <<EOF
135opcontrol: usage:
136 -l/--list-events list event types and unit masks
137 -?/--help this message
138 -v/--version show version
139 --init loads the oprofile module and oprofilefs
140 --setup give setup arguments (may be omitted)
141 --status show configuration
142 --start-daemon start daemon without starting profiling
143 -s/--start start data collection
144 -d/--dump flush the collected profiling data
145 -t/--stop stop data collection
146 -h/--shutdown stop data collection and kill daemon
147 -V/--verbose[=all,sfile,arcs,samples,module,misc,ext]
148 be verbose in the daemon log
149 --reset clears out data from current session
150 --save=name save data from current session to session_name
151 --deinit unload the oprofile module and oprofilefs
152
153 -e/--event=eventspec
154
155 Choose an event. May be specified multiple times. Of the form
156 "default" or "name:count:unitmask:kernel:user", where :
157
158 name: event name, e.g. CPU_CLK_UNHALTED or RTC_INTERRUPTS
159 count: reset counter value e.g. 100000
160 unitmask: hardware unit mask e.g. 0x0f
161 kernel: whether to profile kernel: 0 or 1
162 user: whether to profile userspace: 0 or 1
163
164 -p/--separate=type,[types]
165
166 Separate profiles as follows :
167
168 none: no profile separation
169 library: separate shared library profiles per-application
170 kernel: same as library, plus kernel profiles
171 thread: per-thread/process profiles
172 cpu: per CPU profiles
173 all: all of the above
174
Jeff Brown7a33c862011-02-02 14:00:44 -0800175 -c/--callgraph=#depth enable callgraph sample collection with a
176 maximum depth. Use '0' to disable callgraph
177 profiling.
Mike Dodd8cfa7022010-11-17 11:12:26 -0800178 --session-dir=dir place sample database in dir instead of
179 default location (/var/lib/oprofile)
180 -i/--image=name[,names] list of binaries to profile (default is "all")
181 --vmlinux=file vmlinux kernel image
182 --no-vmlinux no kernel image (vmlinux) available
183 --kernel-range=start,end kernel range vma address in hexadecimal
Jeff Brown7a33c862011-02-02 14:00:44 -0800184 --buffer-size=num kernel buffer size in sample units.
185 Rules: A non-zero value goes into effect after
186 a '--shutdown/start' sequence. A value of
187 zero sets this parameter back to default value
188 but does not go into effect until after a
189 '--deinit/init' sequence.
190 --buffer-watershed kernel buffer watershed in sample units (2.6
191 kernel). Same rules as defined for
192 buffer-size.
193 --cpu-buffer-size=num per-cpu buffer size in units (2.6 kernel)
194 Same rules as defined for buffer-size.
195 --note-table-size kernel notes buffer size in notes units (2.4
196 kernel)
Mike Dodd8cfa7022010-11-17 11:12:26 -0800197
198 --xen Xen image (for Xen only)
Jeff Brown7a33c862011-02-02 14:00:44 -0800199 --active-domains=<list> List of domains in profiling session (for Xen)
Mike Dodd8cfa7022010-11-17 11:12:26 -0800200 (list contains domain ids separated by commas)
201EOF
202}
203
204
205# load the module and mount oprofilefs
206load_module_26()
207{
208 grep oprofilefs /proc/filesystems >/dev/null
209 if test "$?" -ne 0; then
210 modprobe oprofile
211 if test "$?" != "0"; then
212 # couldn't load the module
213 return
214 fi
215 grep oprofile /proc/modules >/dev/null
216 if test "$?" != "0"; then
217 # didn't find module
218 return
219 fi
220 grep oprofilefs /proc/filesystems >/dev/null
221 if test "$?" -ne 0; then
222 # filesystem still not around
223 return
224 fi
225 fi
226 mkdir /dev/oprofile >/dev/null 2>&1
227 grep oprofilefs /etc/mtab >/dev/null
228 if test "$?" -ne 0; then
229 mount -t oprofilefs nodev /dev/oprofile >/dev/null
230 fi
231 KERNEL_SUPPORT=yes
232 OPROFILE_AVAILABLE=yes
233}
234
235
236load_module_24()
237{
238 grep oprof /proc/devices >/dev/null
239 if test "$?" -ne 0; then
240 modprobe oprofile
241 if test "$?" != "0"; then
242 # couldn't load a module
243 return
244 fi
245 grep oprofile /proc/modules >/dev/null
246 if test "$?" != "0"; then
247 # didn't find module
248 return
249 fi
250 fi
251 KERNEL_SUPPORT=no
252 OPROFILE_AVAILABLE=yes
253}
254
255
256load_module()
257{
258 OPROFILE_AVAILABLE=no
259 load_module_26
260 if test "$OPROFILE_AVAILABLE" != "yes"; then
261 load_module_24
262 fi
263 if test "$OPROFILE_AVAILABLE" != "yes"; then
264 echo "Kernel doesn't support oprofile" >&2
265 exit 1
266 fi
267}
268
269# setup variables related to path or daemon. Set vars according to following
270# relationship: command-line-option > config-file-settings > defaults.
271# Note that upon entry SESSION_DIR may be set by command-line option.
272do_init_daemon_vars()
273{
274 # load settings from config file, keeping command-line value
275 # of SESSION_DIR if necessary.
276 if test -n "$SESSION_DIR"; then
277 SAVED=$SESSION_DIR
278 fi
279 do_load_setup
280 if test -n "$SAVED"; then
281 SESSION_DIR=$SAVED
282 fi
283
284 # daemon parameters (as in op_config.h). Note that we preserve
285 # any previous value of SESSION_DIR
286 if test -z "$SESSION_DIR"; then
287 SESSION_DIR="/var/lib/oprofile"
288 fi
289 LOCK_FILE="$SESSION_DIR/lock"
290 SAMPLES_DIR="$SESSION_DIR/samples"
291 LOG_FILE="$SAMPLES_DIR/oprofiled.log"
292 CURRENT_SAMPLES_DIR="$SAMPLES_DIR/current"
293}
294
295
296# pick the appropriate device mount based on kernel
297decide_oprofile_device_mount()
298{
299 if test "$KERNEL_SUPPORT" = "yes"; then
300 MOUNT="/dev/oprofile"
301 else
302 MOUNT="/proc/sys/dev/oprofile"
303 fi
304}
305
306
307# pick the appropriate locations device for oprofile based on kernel
308decide_oprofile_device()
309{
310 if test "$KERNEL_SUPPORT" = "yes"; then
311 DEVICE_FILE="$MOUNT/buffer"
312 else
313 DEVICE_FILE="$SESSION_DIR/opdev"
314 NOTE_DEVICE_FILE="$SESSION_DIR/opnotedev"
315 HASH_MAP_DEVICE_FILE="$SESSION_DIR/ophashmapdev"
316 fi
317}
318
319# initialise parameters
320do_init()
321{
322 # for these three buffer size == 0 means use the default value
323 # hard-coded in op_user.h
324 BUF_SIZE=0
325 BUF_WATERSHED=0
326 CPU_BUF_SIZE=0
327 NOTE_SIZE=0
328 VMLINUX=
329 XENIMAGE="none"
330 VERBOSE=""
331 SEPARATE_LIB=0
332 SEPARATE_KERNEL=0
333 SEPARATE_THREAD=0
334 SEPARATE_CPU=0
335 CALLGRAPH=0
336 IBS_FETCH_EVENTS=""
337 IBS_FETCH_COUNT=0
338 IBS_FETCH_UNITMASK=0
339 IBS_OP_EVENTS=""
340 IBS_OP_COUNT=0
341 IBS_OP_UNITMASK=0
342
343 OPROFILED="$OPDIR/oprofiled"
344
345 # location for daemon setup information
346 SETUP_DIR="/root/.oprofile"
347 SETUP_FILE="$SETUP_DIR/daemonrc"
348
349 # initialize daemon vars
350 decide_oprofile_device_mount
351 CPUTYPE=`cat $MOUNT/cpu_type`
352 OP_COUNTERS=`ls $MOUNT/ | grep "^[0-9]\+\$" | tr "\n" " "`
353 NR_CHOSEN=0
354
355 do_init_daemon_vars
356 decide_oprofile_device
357
358 DEFAULT_EVENT=`$OPHELP --get-default-event`
359
360 IS_TIMER=0
361 IS_PERFMON=0
362 if test "$CPUTYPE" = "timer"; then
363 IS_TIMER=1
364 else
365 case "$CPUTYPE" in
366 ia64/*)
367 IS_PERFMON=$KERNEL_SUPPORT
368 ;;
369 esac
370 fi
371}
372
373
374create_dir()
375{
376 if test ! -d "$1"; then
377 mkdir -p "$1"
378 if test "$?" != "0"; then
379 echo "Couldn't mkdir -p $1" >&2
380 exit 1
381 fi
382 chmod 755 "$1"
383 fi
384}
385
386get_event()
387{
388 GOTEVENT=`eval "echo \\$CHOSEN_EVENTS_$1"`
389}
390
391set_event()
392{
393 eval "CHOSEN_EVENTS_$1=$2"
394}
395
396
397# save all the setup related information
398do_save_setup()
399{
400 create_dir "$SETUP_DIR"
401
402 touch $SETUP_FILE
403 chmod 644 $SETUP_FILE
404 >$SETUP_FILE
405
406 echo "SESSION_DIR=$SESSION_DIR" >>$SETUP_FILE
407
408 if test "$NR_CHOSEN" != "0"; then
409 for f in `seq 0 $((NR_CHOSEN - 1))`; do
410 get_event $f
411 echo "CHOSEN_EVENTS_${f}=$GOTEVENT" >>$SETUP_FILE
412 done
413 fi
414
415 echo "NR_CHOSEN=$NR_CHOSEN" >>$SETUP_FILE
416
417 echo "SEPARATE_LIB=$SEPARATE_LIB" >> $SETUP_FILE
418 echo "SEPARATE_KERNEL=$SEPARATE_KERNEL" >> $SETUP_FILE
419 echo "SEPARATE_THREAD=$SEPARATE_THREAD" >> $SETUP_FILE
420 echo "SEPARATE_CPU=$SEPARATE_CPU" >> $SETUP_FILE
421 echo "VMLINUX=$VMLINUX" >> $SETUP_FILE
422 echo "IMAGE_FILTER=$IMAGE_FILTER" >> $SETUP_FILE
423 # write the actual information to file
424 if test "$BUF_SIZE" != "0"; then
425 echo "BUF_SIZE=$BUF_SIZE" >> $SETUP_FILE
426 fi
427 if test "$BUF_WATERSHED" != "0"; then
428 echo "BUF_WATERSHED=$BUF_WATERSHED" >> $SETUP_FILE
429 fi
430 if test "$KERNEL_SUPPORT" = "yes"; then
431 echo "CPU_BUF_SIZE=$CPU_BUF_SIZE" >> $SETUP_FILE
432 fi
433 if test "$KERNEL_SUPPORT" != "yes"; then
434 echo "NOTE_SIZE=$NOTE_SIZE" >> $SETUP_FILE
435 fi
436 echo "CALLGRAPH=$CALLGRAPH" >> $SETUP_FILE
437 if test "$KERNEL_RANGE"; then
438 echo "KERNEL_RANGE=$KERNEL_RANGE" >> $SETUP_FILE
439 fi
440 echo "XENIMAGE=$XENIMAGE" >> $SETUP_FILE
441 if test "$XEN_RANGE"; then
442 echo "XEN_RANGE=$XEN_RANGE" >> $SETUP_FILE
443 fi
444}
445
446
447# reload all the setup-related information
448do_load_setup()
449{
450 if test -f "$SETUP_FILE"; then
451 # load the actual information from file
452 # FIXME this is insecure, arbitrary commands could be added to
453 # $SETUP_FILE and be executed as root
454 . $SETUP_FILE
455 fi
456}
457
458
459check_valid_args()
460{
461 if test -z "$VMLINUX"; then
462 echo "No vmlinux file specified. You must specify the correct vmlinux file, e.g." >&2
463 echo "opcontrol --vmlinux=/path/to/vmlinux" >&2
464 echo "If you do not have a vmlinux file, use " >&2
465 echo "opcontrol --no-vmlinux" >&2
466 echo "Enter opcontrol --help for full options" >&2
467 exit 1
468 fi
469
470 if test -f "$VMLINUX"; then
471 return
472 fi
473
474 if test "$VMLINUX" = "none"; then
475 return
476 fi
477
478 echo "The specified vmlinux file \"$VMLINUX\" doesn't exist." >&2
479 exit 1
480
481# similar check for Xen image
482 if test -f "$XENIMAGE"; then
483 return
484 fi
485
486 if test "$XENIMAGE" = "none"; then
487 return
488 fi
489
490 echo "The specified XenImage file \"$XENIMAGE\" does not exist." >&2
491 exit 1
492}
493
494
495# get start and end points of a file image (linux kernel or xen)
496# get_image_range parameter: $1=type_of_image (linux or xen)
497get_image_range()
498{
499 if test "$1" = "xen"; then
500 if test ! -z "$XEN_RANGE"; then
501 return;
502 fi
503 FILE_IMAGE="$XENIMAGE"
504 else
505 if test ! -z "$KERNEL_RANGE"; then
506 return;
507 fi
508 FILE_IMAGE="$VMLINUX"
509 fi
510
511 if test "$FILE_IMAGE" = "none"; then
512 return;
513 fi
514
515 if is_tool_available objdump; then
516 echo "objdump is not installed on this system, use opcontrol --kernel-range=start,end or opcontrol --xen-range= or install objdump"
517 exit 1
518 fi
519
520 # start at the start of .text, and end at _etext
521 range_info=`objdump -h $FILE_IMAGE 2>/dev/null | grep " .text "`
522 tmp1=`echo $range_info | awk '{print $4}'`
523 tmp2=`objdump -t $FILE_IMAGE 2>/dev/null | grep "_etext$" | awk '{ print $1 }'`
524
525 if test -z "$tmp1" -o -z "$tmp2"; then
526 echo "The specified file $FILE_IMAGE does not seem to be valid" >&2
527 echo "Make sure you are using the non-compressed image file (e.g. vmlinux not vmlinuz)" >&2
528 vecho "found start as \"$tmp1\", end as \"$tmp2\"" >&2
529 exit 1
530 fi
531
532 if test "$1" = "xen"; then
533 XEN_RANGE="`echo $tmp1`,`echo $tmp2`"
534 vecho "XEN_RANGE $XEN_RANGE"
535 else
536 KERNEL_RANGE="`echo $tmp1`,`echo $tmp2`"
537 vecho "KERNEL_RANGE $KERNEL_RANGE"
538 fi
539}
540
541
542# validate --separate= parameters. This function is called with IFS=,
543# so on each argument is splitted
544validate_separate_args()
545{
546 error_if_empty $1 $2 # we need at least one argument
547 local i=1
548 SEPARATE_LIB=0
549 SEPARATE_KERNEL=0
550 SEPARATE_THREAD=0
551 SEPARATE_CPU=0
552 while [ "$i" -lt "$#" ]; do
553 shift
554 case "$1" in
555 lib|library)
556 SEPARATE_LIB=1
557 ;;
558 kernel)
559 # first implied by second
560 SEPARATE_LIB=1
561 SEPARATE_KERNEL=1
562 ;;
563 thread)
564 SEPARATE_THREAD=1
565 ;;
566 cpu)
567 SEPARATE_CPU=1
568 ;;
569 all)
570 SEPARATE_LIB=1
571 SEPARATE_KERNEL=1
572 SEPARATE_THREAD=1
573 SEPARATE_CPU=1
574 ;;
575 none)
576 SEPARATE_LIB=0
577 SEPARATE_KERNEL=0
578 SEPARATE_THREAD=0
579 SEPARATE_CPU=0
580 ;;
581 *)
582 echo "invalid --separate= argument: $1"
583 exit 1
584 esac
585 done
586}
587
588
589# check the counters make sense, and resolve the hardware allocation
590verify_counters()
591{
592 if test "$IS_TIMER" = 1; then
593 if test "$NR_CHOSEN" != 0; then
594 echo "You cannot specify any performance counter events" >&2
595 echo "because OProfile is in timer mode." >&2
596 exit 1
597 fi
598 return
599 fi
600
601 OPHELP_ARGS=
602
603 if test "$NR_CHOSEN" != 0; then
604 for f in `seq 0 $((NR_CHOSEN - 1))`; do
605 get_event $f
606 if test "$GOTEVENT" != ""; then
607 verify_ibs $GOTEVENT
608 OPHELP_ARGS="$OPHELP_ARGS $GOTEVENT"
609 fi
610 done
611
612 if test ! -z "$OPHELP_ARGS" ; then
613 HW_CTRS=`$OPHELP --check-events $OPHELP_ARGS --callgraph=$CALLGRAPH`
614 if test "$?" != 0; then
615 exit 1
616 fi
617 fi
618 fi
619}
620
621
622# setup any needed default value in chosen events
623normalise_events()
624{
625 if test "$NR_CHOSEN" -le 0 || test "$IS_TIMER" = 1; then
626 return
627 fi
628
629 for f in `seq 0 $((NR_CHOSEN - 1))`; do
630 get_event $f
631 if test "$GOTEVENT" != ""; then
632 EVENT=`echo $GOTEVENT | awk -F: '{print $1}'`
633 EVENT_VAL=`$OPHELP $EVENT`
634 if test "$?" != 0; then
635 exit 1
636 fi
637 COUNT=`echo $GOTEVENT | awk -F: '{print $2}'`
638 UNIT_MASK=`echo $GOTEVENT | awk -F: '{print $3}'`
639 KERNEL=`echo $GOTEVENT | awk -F: '{print $4}'`
640 USER=`echo $GOTEVENT | awk -F: '{print $5}'`
641 if test -z "$UNIT_MASK"; then
642 TMPEVENT="$EVENT:$COUNT"
643 UNIT_MASK=`$OPHELP --unit-mask $TMPEVENT`
644 if test "$?" != 0; then
645 exit 1
646 fi
647 fi
648 if test -z "$KERNEL"; then
649 KERNEL=1
650 fi
651 if test -z "$USER"; then
652 USER=1
653 fi
654
655 set_event $f "$EVENT:$COUNT:$UNIT_MASK:$KERNEL:$USER"
656 fi
657 done
658}
659
660
661# get and check specified options
662do_options()
663{
664 EXCLUSIVE_ARGC=0
665 SETUP=no
666 NEED_SETUP=no
667 SEEN_EVENT=0
668
669 # note: default settings have already been loaded
670
671 while [ "$#" -ne 0 ]
672 do
673 arg=`printf %s $1 | awk -F= '{print $1}'`
674 val=`printf %s $1 | awk -F= '{print $2}'`
675 shift
676 if test -z "$val"; then
677 local possibleval=$1
678 printf %s $1 "$possibleval" | grep ^- >/dev/null 2>&1
679 if test "$?" != "0"; then
680 val=$possibleval
681 if [ "$#" -ge 1 ]; then
682 shift
683 fi
684 fi
685 fi
686
687 case "$arg" in
688
689 --init)
690 # this is already done in load_module
691 # because need to know the processor type
692 # and number of registers
693 INIT=yes;
694 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
695 EXCLUSIVE_ARGV="$arg"
696 ;;
697
698 --setup)
699 SETUP=yes
700 ;;
701
702 --start-daemon)
703 if test "$KERNEL_SUPPORT" != "yes"; then
704 echo "$arg unsupported. use \"--start\"" >&2
705 exit 1
706 fi
707 START_DAEMON=yes
708 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
709 EXCLUSIVE_ARGV="$arg"
710 ;;
711
712 -s|--start)
713 START=yes
714 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
715 EXCLUSIVE_ARGV="$arg"
716 ;;
717
718 -d|--dump)
719 DUMP=yes
720 ONLY_DUMP=yes
721 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
722 EXCLUSIVE_ARGV="$arg"
723 ;;
724
725 -t|--stop)
726 if test "$KERNEL_SUPPORT" != "yes"; then
727 echo "$arg unsupported. use \"--shutdown\"" >&2
728 exit 1
729 fi
730 DUMP=yes
731 STOP=yes
732 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
733 EXCLUSIVE_ARGV="$arg"
734 ;;
735
736 -h|--shutdown)
737 DUMP=yes
738 STOP=yes
739 KILL_DAEMON=yes
740 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
741 EXCLUSIVE_ARGV="$arg"
742 ;;
743
744 --status)
745 STATUS=yes
746 ;;
747
748 --reset)
749 DUMP=yes
750 RESET=yes
751 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
752 EXCLUSIVE_ARGV="$arg"
753 ;;
754
755 --save)
756 error_if_empty $arg $val
757 DUMP=yes
758 SAVE_SESSION=yes
759 SAVE_NAME=$val
760 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
761 EXCLUSIVE_ARGV="$arg"
762 ;;
763
764 --deinit)
765 DUMP=yes
766 test ! -f "$LOCK_FILE" || {
767 STOP=yes
768 KILL_DAEMON=yes
769 }
770 DEINIT=yes
771 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
772 EXCLUSIVE_ARGV="$arg"
773 ;;
774
775 # --setup options
776
777 --session-dir)
778 # already processed
779 ;;
780 --buffer-size)
781 error_if_empty $arg $val
Jeff Brown7a33c862011-02-02 14:00:44 -0800782 error_if_not_number $arg $val
Mike Dodd8cfa7022010-11-17 11:12:26 -0800783 BUF_SIZE=$val
784 DO_SETUP=yes
785 ;;
786 --buffer-watershed)
787 if test "$KERNEL_SUPPORT" != "yes"; then
788 echo "$arg unsupported for this kernel version"
789 exit 1
790 fi
791 error_if_empty $arg $val
Jeff Brown7a33c862011-02-02 14:00:44 -0800792 error_if_not_number $arg $val
Mike Dodd8cfa7022010-11-17 11:12:26 -0800793 BUF_WATERSHED=$val
794 DO_SETUP=yes
795 ;;
796 --cpu-buffer-size)
797 if test "$KERNEL_SUPPORT" != "yes"; then
798 echo "$arg unsupported for this kernel version"
799 exit 1
800 fi
801 error_if_empty $arg $val
Jeff Brown7a33c862011-02-02 14:00:44 -0800802 error_if_not_number $arg $val
Mike Dodd8cfa7022010-11-17 11:12:26 -0800803 CPU_BUF_SIZE=$val
804 DO_SETUP=yes
805 ;;
806 -e|--event)
807 error_if_empty $arg $val
808 # reset any read-in defaults from daemonrc
809 if test "$SEEN_EVENT" = "0"; then
810 NR_CHOSEN=0
811 SEEN_EVENT=1
812 fi
813 if test "$val" = "default"; then
814 val=$DEFAULT_EVENT
815 fi
816 set_event $NR_CHOSEN "$val"
817 NR_CHOSEN=`expr $NR_CHOSEN + 1`
818 DO_SETUP=yes
819 ;;
820 -p|--separate)
821 OLD_IFS=$IFS
822 IFS=,
823 validate_separate_args $arg $val
824 IFS=$OLD_IFS
825 DO_SETUP=yes
826 ;;
827 -c|--callgraph)
828 error_if_empty $arg $val
829 if test ! -f $MOUNT/backtrace_depth; then
830 echo "Call-graph profiling unsupported on this kernel/hardware" >&2
831 exit 1
832 fi
Jeff Brown7a33c862011-02-02 14:00:44 -0800833 error_if_not_number $arg $val
Mike Dodd8cfa7022010-11-17 11:12:26 -0800834 CALLGRAPH=$val
835 DO_SETUP=yes
836 ;;
837 --vmlinux)
838 error_if_empty $arg $val
839 VMLINUX=$val
840 DO_SETUP=yes
841 ;;
842 --no-vmlinux)
843 VMLINUX=none
844 DO_SETUP=yes
845 ;;
846 --kernel-range)
847 error_if_empty $arg $val
848 KERNEL_RANGE=$val
849 DO_SETUP=yes
850 ;;
851 --xen)
852 error_if_empty $arg $val
853 XENIMAGE=$val
854 DO_SETUP=yes
855 ;;
856 --active-domains)
857 error_if_empty $arg $val
858 ACTIVE_DOMAINS=$val
859 DO_SETUP=yes
860 ;;
861 --note-table-size)
862 error_if_empty $arg $val
863 if test "$KERNEL_SUPPORT" = "yes"; then
864 echo "\"$arg\" meaningless on this kernel" >&2
865 exit 1
866 else
867 NOTE_SIZE=$val
868 fi
869 DO_SETUP=yes
870 ;;
871 -i|--image)
872 error_if_empty $arg $val
873 if test "$val" = "all"; then
874 IMAGE_FILTER=
875 else
876 IMAGE_FILTER=$val
877 fi
878 DO_SETUP=yes
879 ;;
880
881 -V|--verbose)
882 if test -z "$val"; then
883 VERBOSE="all"
884 else
885 VERBOSE=$val
886 fi
887 ;;
888
889 -l|--list-events)
890 EXCLUSIVE_ARGC=`expr $EXCLUSIVE_ARGC + 1`
891 EXCLUSIVE_ARGV="$arg"
892 exec $OPHELP
893 ;;
894
895 *)
896 echo "Unknown option \"$arg\". See opcontrol --help" >&2
897 exit 1
898 ;;
899 esac
900 done
901
902 normalise_events
903 verify_counters
904
905 # error checking to make sure options make sense
906 if test "$EXCLUSIVE_ARGC" -gt 1; then
907 echo "Option \"$EXCLUSIVE_ARGV\" not valid with other options." >&2
908 exit 1
909 fi
910
911 if test "$SETUP" = "yes" -a "$DO_SETUP" != "yes"; then
912 echo "No options specified for --setup." >&2
913 exit 1
914 fi
915
916 if test -n "$VERBOSE"; then
917 if test "$START" != "yes" -a "$START_DAEMON" != "yes"; then
918 echo "Option --verbose may only be used with --start or --start-daemon" >&2
919 exit 1
920 fi
921 fi
922
923 if test "$DO_SETUP" = "yes"; then
924 SETUP="$DO_SETUP"
925 fi
926
927 if test "$EXCLUSIVE_ARGC" -eq 1 -a "$SETUP" = "yes"; then
928 if test "$EXCLUSIVE_ARGV" != "--start-daemon" -a "$EXCLUSIVE_ARGV" != "--start"; then
929 echo "Option \"--setup\" not valid with \"$EXCLUSIVE_ARGV\"." >&2
930 exit 1
931 fi
932 fi
933
934 vecho "Parameters used:"
935 vecho "SESSION_DIR $SESSION_DIR"
936 vecho "LOCK_FILE $LOCK_FILE"
937 vecho "SAMPLES_DIR $SAMPLES_DIR"
938 vecho "CURRENT_SAMPLES_DIR $CURRENT_SAMPLES_DIR"
939 vecho "CPUTYPE $CPUTYPE"
940 if test "$BUF_SIZE" != "0"; then
941 vecho "BUF_SIZE $BUF_SIZE"
942 else
943 vecho "BUF_SIZE default value"
944 fi
945 if test "$BUF_WATERSHED" != "0"; then
946 vecho "BUF_WATERSHED $BUF_WATERSHED"
947 else
948 vecho "BUF_WATERSHED default value"
949 fi
950 if test "$KERNEL_SUPPORT" = "yes"; then
951 if test "$CPU_BUF_SIZE" != "0"; then
952 vecho "CPU_BUF_SIZE $CPU_BUF_SIZE"
953 else
954 vecho "CPU_BUF_SIZE default value"
955 fi
956 fi
957
958 vecho "SEPARATE_LIB $SEPARATE_LIB"
959 vecho "SEPARATE_KERNEL $SEPARATE_KERNEL"
960 vecho "SEPARATE_THREAD $SEPARATE_THREAD"
961 vecho "SEPARATE_CPU $SEPARATE_CPU"
962 vecho "CALLGRAPH $CALLGRAPH"
963 vecho "VMLINUX $VMLINUX"
964 vecho "KERNEL_RANGE $KERNEL_RANGE"
965 vecho "XENIMAGE $XENIMAGE"
966 vecho "XEN_RANGE $XEN_RANGE"
967}
968
969
970# stop any existing daemon
971do_stop()
972{
973 if test ! -f "$LOCK_FILE"; then
974 echo "Daemon not running" >&2
975 return
976 fi
977
978 kill -0 `cat $LOCK_FILE` 2>/dev/null
979 if test "$?" -ne 0; then
980 echo "Detected stale lock file. Removing." >&2
981 rm -f "$LOCK_FILE"
982 return
983 fi
984
985 if test $KERNEL_SUPPORT = "yes" \
986 && test 0 != $(cat /dev/oprofile/enable); then
987 echo "Stopping profiling."
988 echo 0 >/dev/oprofile/enable
989 fi
990 kill -USR2 `cat $LOCK_FILE` 2>/dev/null
991}
992
993
994# kill the daemon process(es)
995do_kill_daemon()
996{
997 if test ! -f "$LOCK_FILE"; then
998 # no error message, do_kill_daemon imply stop and stop already
999 # output "Daemon not running"
1000 return
1001 fi
1002
1003 kill -0 `cat $LOCK_FILE` 2>/dev/null
1004 if test "$?" -ne 0; then
1005 echo "Detected stale lock file. Removing." >&2
1006 rm -f "$LOCK_FILE"
1007 return
1008 fi
1009
1010 echo "Killing daemon."
1011
1012 if test $KERNEL_SUPPORT = "yes"; then
1013 kill -TERM `cat $LOCK_FILE`
1014 else
1015 echo 1 >/proc/sys/dev/oprofile/dump_stop
1016 fi
1017
1018 COUNT=0
1019 while test -n "`pidof oprofiled`"
1020 do
1021 sleep 1
1022
1023 # because oprofiled only sets a variable inside the
1024 # signal handler itself, it's possible to miss a
1025 # signal just before it goes to sleep waiting for
1026 # data from the kernel that never arrives. So we
1027 # remind it it needs to die - this works because
1028 # the signal will bring oprofiled out of the kernel
1029 # back into userspace
1030 if test $KERNEL_SUPPORT = "yes"; then
1031 pid=`cat $LOCK_FILE 2>/dev/null`
1032 kill -TERM "$pid" 2>/dev/null
1033 fi
1034
1035 COUNT=`expr $COUNT + 1`
1036
1037 # IBS can generate a large number of samples/events.
1038 # Therefore, extend the delay before killing
1039 if test "$IBS_FETCH_COUNT" != "0" \
1040 -o "$IBS_OP_COUNT" != "0" ; then
1041 DELAY_KILL=60
1042 else
1043 DELAY_KILL=15
1044 fi
1045 if test "$COUNT" -eq "$DELAY_KILL"; then
1046 echo "Daemon stuck shutting down; killing !"
1047 kill -9 `cat $LOCK_FILE`
1048 fi
1049 done
1050 sleep 1
1051 # already removed unless we forced the kill
1052 rm -f "$SESSION_DIR/lock"
Mike Dodd8cfa7022010-11-17 11:12:26 -08001053}
1054
1055
1056rm_devices_24()
1057{
1058 rm_device "$DEVICE_FILE"
1059 rm_device "$NOTE_DEVICE_FILE"
1060 rm_device "$HASH_MAP_DEVICE_FILE"
1061}
1062
1063
1064create_devices_24()
1065{
1066 MAJOR_NR=`grep oprof /proc/devices | awk '{print $1}'`
1067
1068 create_device $DEVICE_FILE $MAJOR_NR 0
1069 create_device $NOTE_DEVICE_FILE $MAJOR_NR 2
1070 create_device $HASH_MAP_DEVICE_FILE $MAJOR_NR 1
1071}
1072
1073# create jitdump directory and remove any old files from
1074# a previous run
1075prep_jitdump() {
1076 local dumpdir=$SESSION_DIR/jitdump
1077 test -d $dumpdir || {
1078 mkdir -p $dumpdir;
1079 chmod 777 $dumpdir;
1080 return;
1081 }
1082 # VMs may already be running when profiling is started, so
1083 # remove only dump files that are not in use
1084 for I in $dumpdir/*; do
1085 test -f $I || continue;
1086 local pid=`basename $I .dump`;
1087 if test -d /proc/$pid; then
1088 local files=`find /proc/$pid/fd -lname $I`;
1089 test -n "$files" && continue;
1090 fi
1091 rm -f $I;
1092 done
1093}
1094
1095# setup and start module
1096do_setup()
1097{
1098 create_dir "$SESSION_DIR"
1099
1100 if test "$KERNEL_SUPPORT" != "yes"; then
1101 rm_devices_24
1102 create_devices_24
1103 fi
1104
1105 create_dir "$CURRENT_SAMPLES_DIR"
1106
1107 prep_jitdump;
1108}
1109
1110
1111# set a sysctl/oprofilefs parameter
1112set_param()
1113{
1114 if test "$KERNEL_SUPPORT" = "yes"; then
1115 echo $2 >$MOUNT/$1
1116 else
1117 $SYSCTL -w dev.oprofile.$1=$2
1118 fi
1119}
1120
1121
1122# set a sysctl/oprofilefs counter parameter
1123set_ctr_param()
1124{
1125 # no such thing for perfmon
1126 if test "$IS_PERFMON" = "yes"; then
1127 return
1128 fi
1129
1130 if test "$KERNEL_SUPPORT" = "yes"; then
1131 if test -e $MOUNT/$1; then
1132 echo $3 >$MOUNT/$1/$2
1133 else
1134 echo -n "Error: counter $1 not available"
1135 if test -e /proc/sys/kernel/nmi_watchdog; then
1136 echo " nmi_watchdog using this resource ? Try:"
1137 echo "opcontrol --deinit"
1138 echo "echo 0 > /proc/sys/kernel/nmi_watchdog"
1139 fi
1140 exit 1
1141 fi
1142 else
1143 $SYSCTL -w dev.oprofile.$1.$2=$3
1144 fi
1145}
1146
1147
1148# returns 1 if $CPUTYPE is a PPC64 variant
1149is_non_cell_ppc64_variant()
1150{
1151 case "$1" in
1152 ppc64/*)
1153 tmp="${1/cell/CELL}"
1154 if test "$1" = "$tmp"; then
1155 #No substituion occurred, so cputype is not cell
1156 return 1
1157 else
1158 return 0
1159 fi
1160 ;;
1161 *)
1162 return 0;
1163 ;;
1164 esac
1165}
1166
1167
1168# The check_event_mapping_data procedure gives the
1169# opportunity to validate events and enforce any
1170# arch-specific restritions, etc.
1171check_event_mapping_data()
1172{
1173
1174 is_non_cell_ppc64_variant $CPUTYPE
1175 if test $? -ne 0 ; then
1176 # For PPC64 architectures, the values required to program
1177 # MMCRs for the given event are returned along with the event.
1178 # Here we use those values to ensure that all chosen events
1179 # are from the same group.
1180 MMCR0=`echo $EVENT_STR | awk '{print $2}'`
1181 MMCR1=`echo $EVENT_STR | awk '{print $3}'`
1182 MMCRA=`echo $EVENT_STR | awk '{print $4}'`
1183 MMCR0_VAL=`echo $MMCR0 | awk -F: '{print $2}'`
1184 MMCR1_VAL=`echo $MMCR1 | awk -F: '{print $2}'`
1185 MMCRA_VAL=`echo $MMCRA | awk -F: '{print $2}'`
1186
1187 ## mmcr0, mmcr1, mmcra are for all ppc64 counters
1188 # Save first event mmcr settings to compare with additional
1189 # events. All events must have the same mmcrx values i.e. be in
1190 # the same group. Only one event is assigned per counter,
1191 # hence there will not be a conflict on the counters
1192 if [ "$MMCR0_CK_VAL" = "" ] ; then
1193 MMCR0_CK_VAL=$MMCR0_VAL
1194 MMCR1_CK_VAL=$MMCR1_VAL
1195 MMCRA_CK_VAL=$MMCRA_VAL
1196 else
1197 # make sure all events are from the same group
1198 if test $MMCR0_CK_VAL != $MMCR0_VAL \
1199 -o $MMCR1_CK_VAL != $MMCR1_VAL \
1200 -o $MMCRA_CK_VAL != $MMCRA_VAL ; then
1201 echo "ERROR: The specified events are not from the same group."
1202 echo " Use 'opcontrol --list-events' to see event groupings."
1203 exit 1
1204 fi
1205 fi
1206
1207 # Check if all user/kernel flags per-counter are matching.
1208 if [ "$USER_CK" = "" ] ; then
1209 USER_CK=$USER
1210 KERNEL_CK=$KERNEL
1211 else
1212 if test $USER_CK != $USER \
1213 -o $KERNEL_CK != $KERNEL ; then
1214 echo "ERROR: All kernel/user event flags must match."
1215 exit 1
1216 fi
1217 fi
1218 fi
1219 if [ "$CPUTYPE" = "ppc64/cell-be" ]; then
1220 event_num=`echo $EVENT_STR | awk '{print $1}'`
1221 # PPU event and cycle events can be measured at
1222 # the same time. SPU event can not be measured
1223 # at the same time as any other event. Similarly for
1224 # SPU Cycles
1225
1226 # We use EVNT_MSK to track what events have already
1227 # been seen. Valid values are:
1228 # NULL string - no events seen yet
1229 # 1 - PPU CYCLES or PPU Event seen
1230 # 2 - SPU CYCLES seen
1231 # 3 - SPU EVENT seen
1232
1233 # check if event is PPU_CYCLES
1234 if [ "$event_num" = "1" ]; then
1235 if [ "$EVNT_MSK" = "1" ] || [ "$EVNT_MSK" = "" ]; then
1236 EVNT_MSK=1
1237 else
1238 echo "PPU CYCLES not compatible with previously specified event"
1239 exit 1
1240 fi
1241
1242 # check if event is SPU_CYCLES
1243 elif [ "$event_num" = "2" ]; then
1244 if [ "$EVNT_MSK" = "" ]; then
1245 EVNT_MSK=2
1246 else
1247 echo "SPU CYCLES not compatible with any other event"
1248 exit 1
1249 fi
1250
1251 # check if event is SPU Event profiling
1252 elif [ "$event_num" -ge "4100" ] && [ "$event_num" -le "4163" ] ; then
1253 if [ "$EVNT_MSK" = "" ]; then
1254 EVNT_MSK=3
1255 else
1256 echo "SPU event profiling not compatible with any other event"
1257 exit 1
1258 fi
1259
1260 # Check to see that the kernel supports SPU event
1261 # profiling. Note, if the file exits it should have
1262 # the LSB bit set to 1 indicating SPU event profiling
1263 # support. For now, it is sufficient to test that the
1264 # file exists.
1265 if test ! -f /dev/oprofile/cell_support; then
1266 echo "Kernel does not support SPU event profiling"
1267 exit 1
1268 fi
1269
1270 # check if event is PPU Event profiling (all other
1271 # events are PPU events)
1272 else
1273 if [ "$EVNT_MSK" = "1" ] || [ "$EVNT_MSK" = "" ]; then
1274 EVNT_MSK=1
1275 else
1276 echo "PPU profiling not compatible with previously specified event"
1277 exit 1
1278 fi
1279 fi
1280 fi
1281 len=`echo -n $event_num | wc -m`
1282 num_chars_in_grpid=`expr $len - 2`
1283 GRP_NUM_VAL=`echo | awk '{print substr("'"${event_num}"'",1,"'"${num_chars_in_grpid}"'")}'`
1284 if [ "$GRP_NUM_CK_VAL" = "" ] ; then
1285 GRP_NUM_CK_VAL=$GRP_NUM_VAL
1286 else
1287 if test $GRP_NUM_CK_VAL != $GRP_NUM_VAL ; then
1288 echo "ERROR: The specified events are not from the same group." >&2
1289 echo " Use 'opcontrol --list-events' to see event groupings." >&2
1290 exit 1
1291 fi
1292 fi
1293}
1294
1295
1296do_param_setup()
1297{
1298 # different names
1299 if test $BUF_SIZE != 0; then
1300 if test "$KERNEL_SUPPORT" = "yes"; then
1301 echo $BUF_SIZE >$MOUNT/buffer_size
1302 else
1303 $SYSCTL -w dev.oprofile.bufsize=$BUF_SIZE
1304 fi
1305 fi
1306
1307 if test $BUF_WATERSHED != 0; then
1308 if test "$KERNEL_SUPPORT" = "yes"; then
1309 echo $BUF_WATERSHED >$MOUNT/buffer_watershed
1310 else
1311 echo "buffer-watershed not supported - ignored" >&2
1312 fi
1313 fi
1314
1315 if test $CPU_BUF_SIZE != 0; then
1316 if test "$KERNEL_SUPPORT" = "yes"; then
1317 echo $CPU_BUF_SIZE >$MOUNT/cpu_buffer_size
1318 else
1319 echo "cpu-buffer-size not supported - ignored" >&2
1320 fi
1321 fi
1322
1323 if test -n "$ACTIVE_DOMAINS"; then
1324 if test "$KERNEL_SUPPORT" = "yes"; then
1325 echo $ACTIVE_DOMAINS >$MOUNT/active_domains
1326 else
1327 echo "active-domains not supported - ignored" >&2
1328 fi
1329 fi
1330
1331 if test $NOTE_SIZE != 0; then
1332 set_param notesize $NOTE_SIZE
1333 fi
1334
1335 if test "$KERNEL_SUPPORT" = "yes" -a -f $MOUNT/backtrace_depth; then
1336 set_param backtrace_depth $CALLGRAPH
1337 elif test "$CALLGRAPH" != "0"; then
1338 echo "Call-graph profiling not supported - ignored" >&2
1339 fi
1340
1341 if test "$IS_TIMER" = 1; then
1342 return
1343 fi
1344
1345 # use the default setup if none set
1346 if test "$NR_CHOSEN" = 0; then
1347 set_event 0 $DEFAULT_EVENT
1348 NR_CHOSEN=1
1349 HW_CTRS=`$OPHELP --check-events $DEFAULT_EVENT --callgraph=$CALLGRAPH`
1350 echo "Using default event: $DEFAULT_EVENT"
1351 fi
1352
1353 # Necessary in this case :
1354 # opcontrol ctr0-on ctr1-on then opcontrol ctr0-on
1355 for f in $OP_COUNTERS ; do
1356 set_ctr_param $f enabled 0
1357 set_ctr_param $f event 0
1358 set_ctr_param $f count 0
1359 done
1360
1361 # Check if driver has IBS support
1362 if test -d $MOUNT/ibs_fetch; then
1363 # Reset driver's IBS fetch setting
1364 set_param ibs_fetch/enable 0
1365 fi
1366
1367 if test -d $MOUNT/ibs_op ; then
1368 # Reset driver's IBS op setting
1369 set_param ibs_op/enable 0
1370 fi
1371
1372 verify_counters
1373
1374 OPROFILED_EVENTS=
1375 for f in `seq 0 $((NR_CHOSEN - 1))`; do
1376 get_event $f
1377 if test "$GOTEVENT" != ""; then
1378 EVENT=`echo $GOTEVENT | awk -F: '{print $1}'`
1379 EVENT_STR=`$OPHELP $EVENT`
1380 EVENT_VAL=`echo $EVENT_STR | awk '{print $1}'`
1381 COUNT=`echo $GOTEVENT | awk -F: '{print $2}'`
1382 UNIT_MASK=`echo $GOTEVENT | awk -F: '{print $3}'`
1383 KERNEL=`echo $GOTEVENT | awk -F: '{print $4}'`
1384 USER=`echo $GOTEVENT | awk -F: '{print $5}'`
1385 CTR=`echo $HW_CTRS | awk "{print \\$$((f + 1))}"`
1386 check_event_mapping_data
1387
1388 if test "$EVENT" = "SPU_CYCLES"; then
1389 if test "$SEPARATE_KERNEL" = "1"; then
1390 SEPARATE_KERNEL=0
1391 echo "Ignoring --separate=kernel option with SPU_CYCLES"
1392 fi
1393 if test "$SEPARATE_LIB" = "0"; then
1394 SEPARATE_LIB=1
1395 echo "Forcing required option --separate=lib with SPU_CYCLES"
1396 fi
1397
1398 # It is possible for a single application to be
1399 # running on all SPUs simultaneously. Without
1400 # SEPARATE_CPU, the resulting sample data would
1401 # consist of a single sample file. If all SPUs
1402 # were truly running the same code, the merging
1403 # of sample data would be fine. However, an
1404 # application file may have multiple SPU images
1405 # embedded within it, resulting in different
1406 # code running on different SPUs. Therefore,
1407 # we force SEPARATE_CPU in order to properly
1408 # handle this case.
1409 if test "$SEPARATE_CPU" = "0"; then
1410 SEPARATE_CPU=1
1411 echo "Forcing required option --separate=cpu with SPU_CYCLES"
1412
1413 fi
1414 fi
1415
1416 if [ "$CTR" = "ibs_fetch" -o "$CTR" = "ibs_op" ] ; then
1417 # Handle IBS events setup
1418 do_param_setup_ibs
1419 continue
1420 fi
1421
1422 if test "$EVENT" = "RTC_INTERRUPTS"; then
1423 set_param rtc_value $COUNT
1424 $SYSCTL -w dev.oprofile.rtc_value=$COUNT
1425 else
1426 set_ctr_param $CTR enabled 1
1427 set_ctr_param $CTR event $EVENT_VAL
1428 loop_count=1
1429 for i in ${EVENT_STR}; do
1430 #Skip first argument of EVENT_STR (event val) since we've already
1431 #processed that value.
1432 if test "$loop_count" -gt 1; then
1433 KEY=`echo $i | awk -F: '{print $1}'`
1434 VAL=`echo $i | awk -F: '{print $2}'`
1435 set_ctr_param "" $KEY $VAL
1436 fi
1437 loop_count=$((loop_count+1))
1438 done
1439 set_ctr_param $CTR count $COUNT
1440 set_ctr_param $CTR kernel $KERNEL
1441 set_ctr_param $CTR user $USER
1442 set_ctr_param $CTR unit_mask $UNIT_MASK
1443 fi
1444 OPROFILED_EVENTS=${OPROFILED_EVENTS}$EVENT:$EVENT_VAL:
1445 OPROFILED_EVENTS=${OPROFILED_EVENTS}$CTR:$COUNT:$UNIT_MASK:
1446 OPROFILED_EVENTS=${OPROFILED_EVENTS}$KERNEL:$USER,
1447 fi
1448 done
1449
1450 # For PPC64 architectures we need to set the enable_kernel and
1451 # enable_user flags for enabling/disabling user/kernel domain
1452 # profiling. All per-counter user/kernel flags must match.
1453 # This condition is checked previously by check_event_mapping_data.
1454 # This statement uses the last event's user/kernel flags to set
1455 # /dev/oprofile/enable_kernel and /dev/oprofile/enable_user.
1456 is_non_cell_ppc64_variant $CPUTYPE
1457 if test $? -ne 0 ; then
1458 set_param "enable_kernel" $KERNEL
1459 set_param "enable_user" $USER
1460 fi
1461
1462}
1463
1464
1465do_start_daemon()
1466{
1467
1468 if test -f "$LOCK_FILE"; then
1469 kill -0 `cat $LOCK_FILE` 2>/dev/null
1470 if test "$?" -eq 0; then
1471 return;
1472 else
1473 echo "Detected stale lock file. Removing." >&2
1474 rm -f "$LOCK_FILE"
1475 fi
1476 fi
1477
1478 do_setup
1479 check_valid_args
1480 get_image_range "linux"
1481 get_image_range "xen"
1482 do_param_setup
1483
1484 OPD_ARGS=" \
1485 --session-dir=$SESSION_DIR \
1486 --separate-lib=$SEPARATE_LIB \
1487 --separate-kernel=$SEPARATE_KERNEL \
1488 --separate-thread=$SEPARATE_THREAD \
1489 --separate-cpu=$SEPARATE_CPU"
1490
1491 if test "$IS_TIMER" = 1; then
1492 OPD_ARGS="$OPD_ARGS --events="
1493 else
1494 if ! test -z "$OPROFILED_EVENTS"; then
1495 OPD_ARGS="$OPD_ARGS --events=$OPROFILED_EVENTS"
1496 fi
1497 fi
1498
1499 if test "$VMLINUX" = "none"; then
1500 OPD_ARGS="$OPD_ARGS --no-vmlinux"
1501 else
1502 OPD_ARGS="$OPD_ARGS --vmlinux=$VMLINUX --kernel-range=$KERNEL_RANGE"
1503 fi
1504
1505 if ! test "$XENIMAGE" = "none"; then
1506 OPD_ARGS="$OPD_ARGS --xen-image=$XENIMAGE --xen-range=$XEN_RANGE"
1507 fi
1508
1509 if ! test -z "$IMAGE_FILTER"; then
1510 OPD_ARGS="$OPD_ARGS --image=$IMAGE_FILTER"
1511 fi
1512
1513 if test -n "$VERBOSE"; then
1514 OPD_ARGS="$OPD_ARGS --verbose=$VERBOSE"
1515 fi
1516
1517 help_start_daemon_with_ibs
1518
1519 vecho "executing oprofiled $OPD_ARGS"
1520
1521 $OPROFILED $OPD_ARGS
1522
1523 COUNT=0
1524 while ! test -f "$SESSION_DIR/lock"
1525 do
1526 sleep 1
1527 COUNT=`expr $COUNT + 1`
1528 if test "$COUNT" -eq 10; then
1529 echo "Couldn't start oprofiled." >&2
1530 echo "Check the log file \"$LOG_FILE\" and kernel syslog" >&2
1531 exit 1
1532 fi
1533 done
1534
1535 echo "Daemon started."
1536}
1537
1538do_start()
1539{
1540 prep_jitdump;
1541 if test "$KERNEL_SUPPORT" = "yes"; then
1542 echo 1 >$MOUNT/enable
1543 fi
1544 kill -USR1 `cat $LOCK_FILE` 2>/dev/null
1545 echo "Profiler running."
1546}
1547
1548
1549# print status
1550do_status()
1551{
1552 OPROFILED_PID=`cat $SESSION_DIR/lock 2>/dev/null`
1553 if test -n "$OPROFILED_PID" -a -d "/proc/$OPROFILED_PID"; then
1554 echo "Daemon running: pid $OPROFILED_PID"
1555 else
1556 echo "Daemon not running"
1557 fi
1558
1559 if test "$NR_CHOSEN" != "0"; then
1560 for f in `seq 0 $((NR_CHOSEN - 1))`; do
1561 get_event $f
1562 echo "Event $f: $GOTEVENT"
1563 done
1564 fi
1565
1566 SEPARATE=""
1567 if test "$SEPARATE_LIB" = "1"; then
1568 SEPARATE="library";
1569 fi
1570 if test "$SEPARATE_KERNEL" = "1"; then
1571 SEPARATE="$SEPARATE kernel";
1572 fi
1573 if test "$SEPARATE_THREAD" = "1"; then
1574 SEPARATE="$SEPARATE thread";
1575 fi
1576 if test "$SEPARATE_CPU" = "1"; then
1577 SEPARATE="$SEPARATE cpu";
1578 fi
1579
1580 if test -z "$SEPARATE"; then
1581 SEPARATE=none
1582 fi
1583
1584 echo "Separate options: $SEPARATE"
1585 echo "vmlinux file: $VMLINUX"
1586
1587 if test -z "$IMAGE_FILTER"; then
1588 echo "Image filter: none"
1589 else
1590 echo "Image filter: $IMAGE_FILTER"
1591 fi
1592
1593 echo "Call-graph depth: $CALLGRAPH"
1594 if test "$BUF_SIZE" != "0"; then
1595 echo "Buffer size: $BUF_SIZE"
1596 fi
1597 if test "$KERNEL_SUPPORT" != "yes"; then
1598 if test "$NOTE_SIZE" != "0"; then
1599 echo "Note buffer size: $NOTE_SIZE"
1600 fi
1601 else
1602 if test "$BUF_WATERSHED" != "0"; then
1603 echo "CPU buffer watershed: $BUF_WATERSHED"
1604 fi
1605 if test "$CPU_BUF_SIZE" != "0"; then
1606 echo "CPU buffer size: $CPU_BUF_SIZE"
1607 fi
1608 fi
1609
1610 exit 0
1611}
1612
1613
1614# do_dump_data
1615# returns 0 if successful
1616# returns 1 if the daemon is unable to dump data
1617# exit 1 if we need to be root to dump
1618do_dump_data()
1619{
1620 # make sure that the daemon is not dead and gone
1621 if test -e "$SESSION_DIR/lock"; then
1622 OPROFILED_PID=`cat $SESSION_DIR/lock`
1623 if test ! -d "/proc/$OPROFILED_PID"; then
1624 echo "dump fail: daemon died during last run ?" >&2
1625 return 1;
1626 fi
1627 else
1628 return 1;
1629 fi
1630
1631 if test "$KERNEL_SUPPORT" = "yes"; then
1632 if ! test -w $MOUNT/dump; then
1633 if test `id -u` != "0"; then
1634 echo "You must be root to dump with this kernel version"
1635 exit 1
1636 fi
1637 fi
1638 # trigger oprofiled to execute opjitconv
Jeff Brown7a33c862011-02-02 14:00:44 -08001639 echo do_jitconv >> $SESSION_DIR/opd_pipe
Mike Dodd8cfa7022010-11-17 11:12:26 -08001640 rm -f "$SESSION_DIR/complete_dump"
1641 echo 1 > $MOUNT/dump
1642 # loop until the complete_dump file is created to
1643 # signal that the dump has been completed
1644 while [ \( ! -e "$SESSION_DIR/complete_dump" \) ]
1645 do
1646 if test ! -d "/proc/$OPROFILED_PID"; then
1647 echo "dump fail: either daemon died during last run or dies during dump" >&2
1648 return 1
1649 fi
1650 sleep 1;
1651 done
1652 else
1653 echo 1 > $MOUNT/dump
1654 # HACK !
1655 sleep 2
1656 fi
Jeff Brown7a33c862011-02-02 14:00:44 -08001657 cp -r /dev/oprofile/stats "$SAMPLES_DIR/current"
1658
Mike Dodd8cfa7022010-11-17 11:12:26 -08001659 return 0;
1660}
1661
1662
1663# do_dump
1664# returns 0 if successful
1665# exits if unsuccessful
1666do_dump()
1667{
1668 do_dump_data
1669 if test $? -ne 0 -a "$ONLY_DUMP" = "yes"; then
1670 echo "Unable to complete dump of oprofile data: is the oprofile daemon running?" >& 2
1671 exit 1;
1672 fi
1673 return 0;
1674}
1675
1676# tell daemon to re-open the sample files
1677hup_daemon()
1678{
1679 if test -f "$LOCK_FILE"; then
1680 echo -n "Signalling daemon... "
1681 kill -HUP `cat $LOCK_FILE`
1682 echo "done"
1683 fi
1684}
1685
1686
1687# move all the sample files to a sample directory
1688do_save_session()
1689{
1690 SAVE_DIR="${SAMPLES_DIR}/${SAVE_NAME}"
1691
1692 if test -e "$SAVE_DIR"; then
1693 echo "session $SAVE_DIR already exists" >&2
1694 exit 1
1695 fi
1696
1697 if ! test -e $CURRENT_SAMPLES_DIR; then
1698 echo "$CURRENT_SAMPLES_DIR doesn't exist: nothing to save" >&2
1699 exit 0
1700 fi
1701
1702 # FIXME: I don't think it's worth checking for empty current directory
1703
1704 mv $CURRENT_SAMPLES_DIR $SAVE_DIR
1705 if test "$?" != "0"; then
1706 echo "Couldn't move $CURRENT_SAMPLES_DIR to $SAVE_DIR" >&2
1707 exit 1
1708 fi
1709
1710 hup_daemon
1711}
1712
1713
1714# remove all the sample files
1715do_reset()
1716{
1717 if test -z "$SAMPLES_DIR"; then
1718 echo "opcontrol:do_reset() SAMPLES_DIR is empty!"
1719 exit 1;
1720 fi
1721
1722 # daemon use {kern} and {root} subdir, it's not a typo to not use ${}
1723 move_and_remove $SAMPLES_DIR/current/{kern}
1724 move_and_remove $SAMPLES_DIR/current/{root}
1725 move_and_remove $SAMPLES_DIR/current/stats
1726
1727 # clear temp directory for jitted code
1728 prep_jitdump;
1729
1730 hup_daemon
1731}
1732
1733
1734do_deinit()
1735{
1736 # unmount /dev/oprofile if it is mounted
1737 OPROF_FS=`grep /dev/oprofile /etc/mtab`
1738 if test -n "$OPROF_FS"; then
1739 umount /dev/oprofile
1740 fi
1741 # unload the oprofile module if it is around
1742 OPROF_MOD=`lsmod | grep oprofile`
1743 if test -n "$OPROF_MOD"; then
1744 echo "Unloading oprofile module" >& 2
1745 rmmod oprofile
1746 fi
1747}
1748
1749
1750# The function that calls the appropriate operations
1751do_operations()
1752{
1753 # INIT always done by load_module to get access to cputype
1754 # thus INIT is a noop
1755
1756 if test "$STATUS" = "yes"; then
1757 do_status
1758 fi
1759
1760 if test "$SETUP" = "yes"; then
1761 check_valid_args
1762 do_save_setup
1763 fi
1764
1765 if test "$START_DAEMON" = "yes"; then
1766 do_start_daemon
1767 fi
1768
1769 if test "$START" = "yes"; then
1770 do_start_daemon
1771 do_start
1772 fi
1773
1774 if test "$DUMP" = "yes"; then
1775 do_dump
1776 fi
1777
1778 if test "$SAVE_SESSION" = "yes"; then
1779 do_save_session
1780 fi
1781
1782 if test "$STOP" = "yes"; then
1783 do_stop
1784 fi
1785
1786 if test "$KILL_DAEMON" = "yes"; then
1787 do_kill_daemon
1788 fi
1789
1790 if test "$RESET" = "yes"; then
1791 do_reset
1792 fi
1793
1794 if test "$DEINIT" = "yes"; then
1795 do_deinit
1796 fi
1797}
1798
1799# early check for --version, --help and --session-dir
1800check_options_early()
1801{
1802
1803 OPHELP="$OPDIR/ophelp"
1804
1805 for i in $@; do
1806 # added to handle arg=val parameters
1807 arg=`printf %s $i | awk -F= '{print $1}'`
1808 val=`printf %s $i | awk -F= '{print $2}'`
1809 case "$arg" in
1810 -\?|--help)
1811 do_help
1812 exit 0
1813 ;;
1814
1815 -v|--version)
1816 echo -n "`basename $0`: "
1817 $OPHELP --version | cut -d' ' -f2-
1818 exit 0
1819 ;;
1820 --session-dir)
1821 error_if_empty $arg $val
1822 SESSION_DIR="$val"
1823 DO_SETUP=yes
1824 # do not exit early
1825 ;;
1826
1827 esac
1828 done
1829}
1830
1831
1832# determine which module is loaded
1833check_version()
1834{
1835 OPROFILE_AVAILABLE=no
1836 grep oprofilefs /etc/mtab >/dev/null
1837 if test "$?" -eq 0; then
1838 # need to have oprofilefs mounted for this to work on 2.6
1839 KERNEL_SUPPORT=yes
1840 OPROFILE_AVAILABLE=yes
1841 return
1842 fi
1843 # need to have /proc/oprof available for this to work on 2.4
1844 grep oprof /proc/devices >/dev/null
1845 if test "$?" -eq 0; then
1846 KERNEL_SUPPORT=no
1847 OPROFILE_AVAILABLE=yes
1848 return
1849 fi
1850}
1851
1852# error out if the module is not loaded
1853check_oprofile_available()
1854{
1855 if test "$OPROFILE_AVAILABLE" != "yes"; then
1856 echo "Kernel support not available, missing opcontrol --init as root ?"
1857 exit 1
1858 fi
1859}
1860
1861
1862try_reset_sample_file()
1863{
1864 # special case to avoid loading the module, it works only if the
1865 # daemon is not running because --reset imply --dump. Rather to check
1866 # if the daemon is running we check if the module is loaded because
1867 # we are only trying to avoid its load, if the check fails we fallback
1868 # to the normal dump / reset sequence.
1869 if test -z "$2" -a "$1" = "--reset"; then
1870 check_version
1871 if test "$OPROFILE_AVAILABLE" != "yes"; then
1872 do_init_daemon_vars
1873 do_reset
1874 exit 0
1875 fi
1876 fi
1877}
1878
1879#
1880# Begin IBS Specific Functions
1881#
1882verify_ibs()
1883{
1884 IBS_EVENT=`echo $1| awk -F: '{print $1}'`
1885 IBS_COUNT=`echo $1 | awk -F: '{print $2}'`
1886 IBS_MASK=`echo $1 | awk -F: '{print $3}'`
1887
1888 IBS_TYPE=`$OPHELP --check-events $1`
1889 if test "$?" != "0" ; then
1890 exit 1
1891 fi
1892
1893 if [ "$IBS_TYPE" = "ibs_fetch " ] ; then
1894 # Check IBS_COUNT consistency
1895 if test "$IBS_FETCH_COUNT" = "0" ; then
1896 IBS_FETCH_COUNT=$IBS_COUNT
1897 IBS_FETCH_MASK=$IBS_MASK
1898 elif test "$IBS_FETCH_COUNT" != "$IBS_COUNT" ; then
Jeff Brown7a33c862011-02-02 14:00:44 -08001899 echo "ERROR: All IBS Fetch must have the same count."
Mike Dodd8cfa7022010-11-17 11:12:26 -08001900 exit 1
1901 fi
1902
1903 # Check IBS_MASK consistency
1904 if test "$IBS_FETCH_MASK" != "$IBS_MASK" ; then
Jeff Brown7a33c862011-02-02 14:00:44 -08001905 echo "ERROR: All IBS Fetch must have the same unitmask."
1906 exit 1
1907 fi
1908
1909 # Check IBS_FETCH_COUNT within range
1910 if test "$IBS_FETCH_COUNT" -gt 1048575 ; then
1911 echo "ERROR: IBS Fetch count is too large."
1912 echo " The maximum IBS-fetch count is 1048575."
Mike Dodd8cfa7022010-11-17 11:12:26 -08001913 exit 1
1914 fi
1915
1916 elif [ "$IBS_TYPE" = "ibs_op " ] ; then
1917 # Check IBS_COUNT consistency
1918 if test "$IBS_OP_COUNT" = "0" ; then
1919 IBS_OP_COUNT=$IBS_COUNT
1920 IBS_OP_MASK=$IBS_MASK
1921 elif test "$IBS_OP_COUNT" != "$IBS_COUNT" ; then
1922 echo "All IBS Op must have the same count."
1923 exit 1
1924 fi
1925
1926 # Check IBS_MASK consistency
1927 if test "$IBS_OP_MASK" != "$IBS_MASK" ; then
1928 echo "All IBS Op must have the same unitmask."
1929 exit 1
1930 fi
Jeff Brown7a33c862011-02-02 14:00:44 -08001931
1932 # Check IBS_OP_COUNT within range
1933 case "$CPUTYPE" in
1934 x86-64/family10)
1935 if test "$IBS_OP_COUNT" -gt 1048575 ; then
1936 echo "ERROR: IBS Op count is too large."
1937 echo " The maximum IBS-fetch count is 1048575."
1938 exit 1
1939 fi
1940 ;;
1941
1942 x86-64/family12h|\
1943 x86-64/family14h|\
1944 x86-64/family15h)
1945 if test "$IBS_OP_COUNT" -gt 134217727 ; then
1946 echo "ERROR: IBS Op count is too large."
1947 echo " The maximum IBS-Op count is 134217727."
1948 exit 1
1949 fi
1950 ;;
1951 *)
1952 esac
Mike Dodd8cfa7022010-11-17 11:12:26 -08001953 fi
1954
1955 return
1956}
1957
1958
1959do_param_setup_ibs()
1960{
1961 if test "$KERNEL_SUPPORT" != "yes" ; then
1962 echo "ERROR: No kernel support for IBS profiling."
1963 exit 1
1964 fi
1965
1966 # Check if driver has IBS support
1967 if test ! -d $MOUNT/ibs_fetch -o ! -d $MOUNT/ibs_op ; then
1968 echo "ERROR: No kernel support for IBS profiling."
1969 exit 1
1970 fi
1971
1972 if test `echo $EVENT | \
1973 awk '{ print substr($0, 1, 10)}'` = "IBS_FETCH_" ; then
1974 if test "$COUNT" != "0"; then
1975 if [ "$IBS_FETCH_EVENTS" = "" ] ; then
1976 IBS_FETCH_EVENTS="$EVENT"
1977 else
1978 IBS_FETCH_EVENTS="$IBS_FETCH_EVENTS,$EVENT"
1979 fi
1980 IBS_FETCH_COUNT=$COUNT
1981 set_param ibs_fetch/max_count $COUNT
1982 set_param ibs_fetch/rand_enable 1
1983 set_param ibs_fetch/enable 1
1984 else
1985 set_param ibs_fetch/enable 0
1986 fi
1987
1988 elif test `echo $EVENT | \
1989 awk '{ print substr($0, 1, 7)}'` = "IBS_OP_" ; then
1990 if test "$COUNT" != "0"; then
1991 if [ "$IBS_OP_EVENTS" = "" ] ; then
1992 IBS_OP_EVENTS="$EVENT"
1993 else
1994 IBS_OP_EVENTS="$IBS_OP_EVENTS,$EVENT"
1995 fi
1996 IBS_OP_COUNT=$COUNT
1997 IBS_OP_UNITMASK=$UNIT_MASK
1998
1999 set_param ibs_op/max_count $COUNT
2000 set_param ibs_op/enable 1
2001
2002 # NOTE: We default to use dispatched_op if available.
2003 # Some of the older family10 system does not have
2004 # dispatched_ops feature.
Jeff Brown7a33c862011-02-02 14:00:44 -08002005 # Dispatched op is enabled by bit 0 of the unitmask
2006 IBS_OP_DISPATCHED_OP=$(( IBS_OP_UNITMASK & 0x1 ))
Mike Dodd8cfa7022010-11-17 11:12:26 -08002007 if test -f $MOUNT/ibs_op/dispatched_ops ; then
Mike Dodd8cfa7022010-11-17 11:12:26 -08002008 set_param ibs_op/dispatched_ops $IBS_OP_DISPATCHED_OP
Jeff Brown7a33c862011-02-02 14:00:44 -08002009 else
2010 if test $IBS_OP_DISPATCHED_OP -eq 1 ; then
2011 echo "ERROR: IBS Op dispatched ops is not supported."
2012 exit 1
2013 fi
2014 fi
2015
2016 # NOTE: BTA is enabled by bit 2 of the unitmask
2017 IBS_OP_BTA=$(( IBS_OP_UNITMASK & 0x4 ))
2018 if test -f $MOUNT/ibs_op/branch_target; then
2019 if [ "$IBS_OP_BTA" = "4" ] ; then
2020 set_param ibs_op/branch_target 1
2021 else
2022 set_param ibs_op/branch_target 0
2023 fi
2024
2025 # TODO: Check if write successful
2026 else
2027 if test $IBS_OP_BTA -eq 1 ; then
2028 echo "ERROR: IBS Op Branch Target Address is not supported."
2029 exit 1
2030 fi
Mike Dodd8cfa7022010-11-17 11:12:26 -08002031 fi
2032 else
2033 set_param ibs_op/enable 0
2034 fi
2035 fi
2036}
2037
2038
2039help_start_daemon_with_ibs()
2040{
2041 if test "$IBS_FETCH_COUNT" != "0" -o "$IBS_OP_COUNT" != "0" ; then
2042 OPD_ARGS="${OPD_ARGS} --ext-feature=ibs:"
2043 if test "$IBS_FETCH_COUNT" != "0"; then
2044 OPD_ARGS="${OPD_ARGS}fetch:$IBS_FETCH_EVENTS:$IBS_FETCH_COUNT:$IBS_FETCH_UNITMASK|"
2045 fi
2046
2047 if test "$IBS_OP_COUNT" != "0"; then
2048 OPD_ARGS="${OPD_ARGS}op:$IBS_OP_EVENTS:$IBS_OP_COUNT:$IBS_OP_UNITMASK"
2049 fi
2050 fi
2051}
2052
2053#
2054# End IBS Specific Functions
2055#
2056
2057# main
2058
2059# determine the location of opcontrol and related programs
2060if test -z "$OPDIR"; then
2061 BINDIR="/usr/bin"
2062 OPCONTROL=`$BINDIR/which $0`
2063 OPDIR=`$BINDIR/dirname $OPCONTROL`
2064fi
2065
2066PATH=$OPDIR:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin
2067
2068check_options_early $@
2069
2070if test -z "$1"; then
2071 do_help
2072 exit 0
2073fi
2074
2075if test `id -u` = "0"; then
2076 try_reset_sample_file $@
2077
2078 load_module
2079fi
2080check_version
2081
2082# Except --reset, even the few operations allowed as non root needs the
2083# kernel support, if we don't error out now the error message will be obscure
2084check_oprofile_available
2085
2086do_init
2087if test `id -u` != "0"; then
2088 if test -z "$2"; then
2089 case "$1" in
2090 --dump|-d)
2091 ONLY_DUMP=yes
2092 do_dump
2093 exit 0;
2094 ;;
2095 --list-events|-l)
2096 exec $OPHELP
2097 exit 0;
2098 ;;
2099 *)
2100 echo "Normal users are limited to either '--dump' or '--list-events'." >&2
2101 exit 1
2102 ;;
2103 esac
2104 else
2105 echo "Normal users are limited to either '--dump' or '--list-events'." >&2
2106 exit 1
2107 fi
2108fi
2109
2110do_options $@
2111do_operations