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