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