diff -PNaur oprofile-0.8.1-orig/daemon/init.c oprofile-0.8.1-testing/daemon/init.c --- oprofile-0.8.1-orig/daemon/init.c 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/init.c 2005-04-06 13:40:16.000000000 +0200 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "config.h" @@ -221,6 +224,7 @@ size_t opd_buf_size; opd_create_vmlinux(vmlinux, kernel_range); + opd_create_xen(xenimage, xen_range); opd_buf_size = opd_read_fs_int("/dev/oprofile/", "buffer_size", 1); kernel_pointer_size = opd_read_fs_int("/dev/oprofile/", "pointer_size", 1); diff -PNaur oprofile-0.8.1-orig/daemon/opd_interface.h oprofile-0.8.1-testing/daemon/opd_interface.h --- oprofile-0.8.1-orig/daemon/opd_interface.h 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/opd_interface.h 2005-04-06 13:40:51.000000000 +0200 @@ -8,6 +8,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #ifndef OPD_INTERFACE_H @@ -17,11 +20,13 @@ #define CPU_SWITCH_CODE 2 #define COOKIE_SWITCH_CODE 3 #define KERNEL_ENTER_SWITCH_CODE 4 -#define KERNEL_EXIT_SWITCH_CODE 5 +#define USER_ENTER_SWITCH_CODE 5 #define MODULE_LOADED_CODE 6 #define CTX_TGID_CODE 7 #define TRACE_BEGIN_CODE 8 #define TRACE_END_CODE 9 -#define LAST_CODE 10 +#define XEN_ENTER_SWITCH_CODE 10 +#define DOMAIN_SWITCH_CODE 11 +#define LAST_CODE 12 #endif /* OPD_INTERFACE_H */ diff -PNaur oprofile-0.8.1-orig/daemon/opd_kernel.c oprofile-0.8.1-testing/daemon/opd_kernel.c --- oprofile-0.8.1-orig/daemon/opd_kernel.c 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/opd_kernel.c 2005-04-06 13:41:22.000000000 +0200 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "opd_kernel.h" @@ -27,8 +30,12 @@ static LIST_HEAD(modules); +static LIST_HEAD(other_domains); + static struct kernel_image vmlinux_image; +static struct kernel_image xen_image; + void opd_create_vmlinux(char const * name, char const * arg) { /* vmlinux is *not* on the list of modules */ @@ -54,6 +61,43 @@ } } +void opd_create_xen(char const * name, char const * arg) +{ + /* xen is *not* on the list of modules */ + list_init(&xen_image.list); + + /* for no xen */ + if (no_xen) { + xen_image.name = "no-xen"; + return; + } + + xen_image.name = xstrdup(name); + + sscanf(arg, "%llx,%llx", &xen_image.start, &xen_image.end); + + verbprintf(vmisc, "xen_start = %llx, xen_end = %llx\n", + xen_image.start, xen_image.end); + + if (!xen_image.start && !xen_image.end) { + fprintf(stderr, "error: mis-parsed xen range: %llx-%llx\n", + xen_image.start, xen_image.end); + exit(EXIT_FAILURE); + } +} + +static struct kernel_image * +opd_create_domain(char const *name) +{ + struct kernel_image * image = xmalloc(sizeof(struct kernel_image)); + + image->name = xstrdup(name); + image->start = 0; + image->end = 0; + list_add(&image->list, &other_domains); + + return image; +} /** * Allocate and initialise a kernel image description @@ -166,6 +210,7 @@ op_close_file(fp); } +extern long long other_domain; /** * find a kernel image by PC value @@ -192,5 +237,20 @@ return image; } + if (xen_image.start <= trans->pc && xen_image.end > trans->pc) + return &xen_image; + + if (other_domain != -1) { + char name[64]; + list_for_each(pos, &other_domains) { + image = list_entry(pos, struct kernel_image, list); + if (image->name[strlen(image->name)] == other_domain + '0') + return image; + } + sprintf (name, "__domain_%d", (int)other_domain); + image = opd_create_domain(name); + return image; + } + return NULL; } diff -PNaur oprofile-0.8.1-orig/daemon/opd_kernel.h oprofile-0.8.1-testing/daemon/opd_kernel.h --- oprofile-0.8.1-orig/daemon/opd_kernel.h 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/opd_kernel.h 2005-04-06 13:41:42.000000000 +0200 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #ifndef OPD_KERNEL_H @@ -20,6 +23,8 @@ /** create the kernel image */ void opd_create_vmlinux(char const * name, char const * arg); +void opd_create_xen(char const * name, char const * arg); + /** opd_reread_module_info - parse /proc/modules for kernel modules */ void opd_reread_module_info(void); diff -PNaur oprofile-0.8.1-orig/daemon/opd_trans.c oprofile-0.8.1-testing/daemon/opd_trans.c --- oprofile-0.8.1-orig/daemon/opd_trans.c 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/opd_trans.c 2005-04-06 13:42:16.000000000 +0200 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "opd_trans.h" @@ -189,7 +192,7 @@ } -static void code_kernel_exit(struct transient * trans) +static void code_user_enter(struct transient * trans) { verbprintf(vmisc, "KERNEL_EXIT_SWITCH to user-space\n"); trans->in_kernel = 0; @@ -218,6 +221,30 @@ trans->tracing = TRACING_OFF; } +static void code_xen_enter(struct transient *trans) +{ + verbprintf(vmisc, "XEN_ENTER_SWITCH to xen\n"); + trans->in_kernel = 1; + trans->current = NULL; + /* subtlety: we must keep trans->cookie cached, + * even though it's meaningless for Xen - + * we won't necessarily get a cookie switch on + * Xen exit. See comments in opd_sfile.c. + * It seems that we can get away with in_kernel = 1 as long as we + * supply the correct Xen image, and its address range in startup + * find_kernel_image is modified to look in the Xen image also + */ +} + +long long other_domain = -1; + +static void code_domain_switch(struct transient *trans) +{ + /* We have to remember the old kernel value, so we do the safe thing: increment */ + trans->in_kernel++; + trans->current = NULL; + other_domain = pop_buffer_value(trans); +} typedef void (*handler_t)(struct transient *); @@ -227,12 +254,14 @@ &code_cpu_switch, &code_cookie_switch, &code_kernel_enter, - &code_kernel_exit, + &code_user_enter, &code_module_loaded, /* tgid handled differently */ &code_unknown, &code_trace_begin, &code_trace_end, + &code_xen_enter, + &code_domain_switch, }; @@ -265,7 +294,17 @@ code = pop_buffer_value(&trans); if (!is_escape_code(code)) { + /* dirty dirty */ + if (other_domain != -1) + code = ~0ULL; opd_put_sample(&trans, code); + if (other_domain != -1) { + /* if last sample was for another domain, + restore trans fields */ + other_domain = -1; + trans.current = NULL; + trans.in_kernel--; + } continue; } diff -PNaur oprofile-0.8.1-orig/daemon/oprofiled.c oprofile-0.8.1-testing/daemon/oprofiled.c --- oprofile-0.8.1-orig/daemon/oprofiled.c 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/oprofiled.c 2005-04-06 13:42:50.000000000 +0200 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include "config.h" @@ -60,6 +63,9 @@ int no_vmlinux; char * vmlinux; char * kernel_range; +int no_xen; +char * xenimage; +char * xen_range; static char * verbose; static char * binary_name_filter; static char * events; @@ -75,6 +81,9 @@ { "kernel-range", 'r', POPT_ARG_STRING, &kernel_range, 0, "Kernel VMA range", "start-end", }, { "vmlinux", 'k', POPT_ARG_STRING, &vmlinux, 0, "vmlinux kernel image", "file", }, { "no-vmlinux", 0, POPT_ARG_NONE, &no_vmlinux, 0, "vmlinux kernel image file not available", NULL, }, + { "xen-range", 0, POPT_ARG_STRING, &xen_range, 0, "Xen VMA range", "start-end", }, + { "xen-image", 0, POPT_ARG_STRING, &xenimage, 0, "Xen image", "file", }, + { "no-xen", 0, POPT_ARG_NONE, &no_xen, 0, "xen image not available", NULL, }, { "image", 0, POPT_ARG_STRING, &binary_name_filter, 0, "image name filter", "profile these comma separated image" }, { "separate-lib", 0, POPT_ARG_INT, &separate_lib, 0, "separate library samples for each distinct application", "[0|1]", }, { "separate-kernel", 0, POPT_ARG_INT, &separate_kernel, 0, "separate kernel samples for each distinct application", "[0|1]", }, @@ -402,6 +411,27 @@ } } + if (!no_xen) { + if (!xenimage || !strcmp("", xenimage)) { + fprintf(stderr, "oprofiled: no xen image specified.\n"); + poptPrintHelp(optcon, stderr, 0); + exit(EXIT_FAILURE); + } + + /* canonicalise xen image filename. fix #637805 */ + tmp = xmalloc(PATH_MAX); + if (realpath(xenimage, tmp)) + xenimage = tmp; + else + free(tmp); + + if (!xen_range || !strcmp("", xen_range)) { + fprintf(stderr, "oprofiled: no Xen VMA range specified.\n"); + poptPrintHelp(optcon, stderr, 0); + exit(EXIT_FAILURE); + } + } + opd_parse_events(events); opd_parse_image_filter(); diff -PNaur oprofile-0.8.1-orig/daemon/oprofiled.h oprofile-0.8.1-testing/daemon/oprofiled.h --- oprofile-0.8.1-orig/daemon/oprofiled.h 2004-05-29 19:02:58.000000000 +0200 +++ oprofile-0.8.1-testing/daemon/oprofiled.h 2005-04-06 13:43:15.000000000 +0200 @@ -7,6 +7,9 @@ * * @author John Levon * @author Philippe Elie + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #ifndef OPROFILED_H @@ -68,5 +71,8 @@ extern int no_vmlinux; extern char * vmlinux; extern char * kernel_range; +extern int no_xen; +extern char * xenimage; +extern char * xen_range; #endif /* OPROFILED_H */ diff -PNaur oprofile-0.8.1-orig/stamp-h1 oprofile-0.8.1-testing/stamp-h1 --- oprofile-0.8.1-orig/stamp-h1 1970-01-01 01:00:00.000000000 +0100 +++ oprofile-0.8.1-testing/stamp-h1 2005-02-02 20:15:22.000000000 +0100 @@ -0,0 +1 @@ +timestamp for config.h diff -PNaur oprofile-0.8.1-orig/utils/opcontrol oprofile-0.8.1-testing/utils/opcontrol --- oprofile-0.8.1-orig/utils/opcontrol 2004-07-07 00:20:44.000000000 +0200 +++ oprofile-0.8.1-testing/utils/opcontrol 2005-01-25 21:48:06.000000000 +0100 @@ -245,6 +245,7 @@ CPU_BUF_SIZE=0 NOTE_SIZE=0 VMLINUX= + XENIMAGE="none" VERBOSE="" SEPARATE_LIB=0 SEPARATE_KERNEL=0 @@ -383,6 +384,18 @@ echo "The specified vmlinux file \"$VMLINUX\" doesn't exist." >&2 exit 1 + +# aravind: similar check for Xen image + if test -f "$XENIMAGE"; then + return + fi + + if test "$XENIMAGE" = "none"; then + return + fi + + echo "The spcefified XenImage file \"$XENIMAGE\" does not exist." >&2 + exit 1 } @@ -414,6 +427,32 @@ vecho "KERNEL_RANGE $KERNEL_RANGE" } +# get start and end points of xen +get_xen_range() +{ + if test ! -z "$XEN_RANGE"; then + return; + fi + + if test "$XENIMAGE" = "none"; then + return; + fi + + # start from section 0 and then continue till end of .text + range_info=`objdump -h $XENIMAGE 2>/dev/null | grep -w "0 "` + tmp1=`echo $range_info | awk '{print $4}'` + range_info=`objdump -h $XENIMAGE 2>/dev/null | grep " .text "` + tmp_length=`echo $range_info | awk '{print $3}'` + tmp2=`objdump -h $XENIMAGE --adjust-vma=0x$tmp_length 2>/dev/null | grep " .text " | awk '{print $4}'` + + if test -z "$tmp1" -o -z "$tmp2"; then + echo "The specified file $XENIMAGE does not seem to be valid" >&2 + vecho "found start as \"$tmp1\", end as \"$tmp2\"" >&2 + exit 1 + fi + XEN_RANGE="`echo $tmp1`,`echo $tmp2`" + vecho "XEN_RANGE $XEN_RANGE" +} # validate --separate= parameters. This function is called with IFS=, # so on each argument is splitted @@ -698,6 +737,23 @@ KERNEL_RANGE=$val DO_SETUP=yes ;; +# aravind menon: xen image option + --xen) + error_if_empty $arg $val + XENIMAGE=$val + DO_SETUP=yes + get_xen_range + ;; + --active-domains) + error_if_empty $arg $val + ACTIVE_DOMAINS=$val + DO_SETUP=yes + ;; + --passive-domains) + error_if_empty $arg $val + PASSIVE_DOMAINS=$val + DO_SETUP=yes + ;; --note-table-size) error_if_empty $arg $val if test $"KERNEL_SUPPORT" = "yes"; then @@ -929,6 +985,22 @@ fi fi + if test -n "$ACTIVE_DOMAINS"; then + if test "$KERNEL_SUPPORT" = "yes"; then + echo $ACTIVE_DOMAINS >$MOUNT/active_domains + else + echo "active-domains not supported - ignored" >&2 + fi + fi + + if test -n "$PASSIVE_DOMAINS"; then + if test "$KERNEL_SUPPORT" = "yes"; then + echo $PASSIVE_DOMAINS >$MOUNT/passive_domains + else + echo "passive-domains not supported - ignored" >&2 + fi + fi + if test $NOTE_SIZE != 0; then set_param notesize $NOTE_SIZE fi @@ -1024,6 +1096,12 @@ OPD_ARGS="$OPD_ARGS --vmlinux=$VMLINUX --kernel-range=$KERNEL_RANGE" fi + if test "$XENIMAGE" = "none"; then + OPD_ARGS="$OPD_ARGS --no-xen" + else + OPD_ARGS="$OPD_ARGS --xen-image=$XENIMAGE --xen-range=$XEN_RANGE" + fi + if ! test -z "$IMAGE_FILTER"; then OPD_ARGS="$OPD_ARGS --image=$IMAGE_FILTER" fi