opcontrol revision 8cfa702f803c5ef6a2b062a489a1b2cf66b45b5e
1#!/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 2021