[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Add backtrace support to xenoprof.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1181223021 -3600
# Node ID a7601de2f733719ed22c2069185bb17d1c5cf59f
# Parent  1cae82505e9e11bcf47f0857917cd20b2d0bad26
Add backtrace support to xenoprof.

Signed-off-by: Amitabha Roy <amitabha.roy@xxxxxxxxx>
Reviewed-by: Jose Renato G Santos <joserenato.santos@xxxxxx>
---
 xen/Rules.mk                            |   32 +++---
 xen/arch/ia64/xen/oprofile/perfmon.c    |    7 +
 xen/arch/x86/oprofile/Makefile          |    1 
 xen/arch/x86/oprofile/backtrace.c       |  132 ++++++++++++++++++++++++++
 xen/arch/x86/oprofile/op_model_athlon.c |    6 -
 xen/arch/x86/oprofile/op_model_p4.c     |    8 -
 xen/arch/x86/oprofile/op_model_ppro.c   |    6 -
 xen/arch/x86/traps.c                    |    2 
 xen/common/xenoprof.c                   |  159 ++++++++++++++++++++++----------
 xen/include/asm-ia64/xenoprof.h         |   12 ++
 xen/include/asm-x86/xenoprof.h          |   11 ++
 xen/include/public/xenoprof.h           |    8 +
 xen/include/xen/xenoprof.h              |    2 
 13 files changed, 312 insertions(+), 74 deletions(-)

diff -r 1cae82505e9e -r a7601de2f733 xen/Rules.mk
--- a/xen/Rules.mk      Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/Rules.mk      Thu Jun 07 14:30:21 2007 +0100
@@ -3,10 +3,11 @@
 # If you change any of these configuration options then you must
 # 'make clean' before rebuilding.
 #
-verbose     ?= n
-perfc       ?= n
-perfc_arrays?= n
-crash_debug ?= n
+verbose       ?= n
+perfc         ?= n
+perfc_arrays  ?= n
+crash_debug   ?= n
+frame_pointer ?= n
 
 XEN_ROOT=$(BASEDIR)/..
 include $(XEN_ROOT)/Config.mk
@@ -14,10 +15,14 @@ include $(XEN_ROOT)/Config.mk
 # Hardcoded configuration implications and dependencies.
 # Do this is a neater way if it becomes unwieldy.
 ifeq ($(debug),y)
-verbose := y
+verbose       := y
+frame_pointer := y
 endif
 ifeq ($(perfc_arrays),y)
 perfc := y
+endif
+ifeq ($(frame_pointer),y)
+CFLAGS := $(shell echo $(CFLAGS) | sed -e 's/-f[^ ]*omit-frame-pointer//g')
 endif
 
 # Set ARCH/SUBARCH appropriately.
@@ -50,18 +55,19 @@ ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/a
 ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o
 ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
 
-CFLAGS-y               += -g -D__XEN__
-CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY
-CFLAGS-$(verbose)      += -DVERBOSE
-CFLAGS-$(crash_debug)  += -DCRASH_DEBUG
-CFLAGS-$(perfc)        += -DPERF_COUNTERS
-CFLAGS-$(perfc_arrays) += -DPERF_ARRAYS
+CFLAGS-y                += -g -D__XEN__
+CFLAGS-$(ACM_SECURITY)  += -DACM_SECURITY
+CFLAGS-$(verbose)       += -DVERBOSE
+CFLAGS-$(crash_debug)   += -DCRASH_DEBUG
+CFLAGS-$(perfc)         += -DPERF_COUNTERS
+CFLAGS-$(perfc_arrays)  += -DPERF_ARRAYS
+CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
 
 ifneq ($(max_phys_cpus),)
-CFLAGS-y               += -DMAX_PHYS_CPUS=$(max_phys_cpus)
+CFLAGS-y                += -DMAX_PHYS_CPUS=$(max_phys_cpus)
 endif
 
-AFLAGS-y               += -D__ASSEMBLY__
+AFLAGS-y                += -D__ASSEMBLY__
 
 ALL_OBJS := $(ALL_OBJS-y)
 
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/ia64/xen/oprofile/perfmon.c
--- a/xen/arch/ia64/xen/oprofile/perfmon.c      Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/arch/ia64/xen/oprofile/perfmon.c      Thu Jun 07 14:30:21 2007 +0100
@@ -37,7 +37,7 @@
 #include <asm/ptrace.h>
 
 // XXX move them to an appropriate header file
-extern void xenoprof_log_event(struct vcpu *vcpu,
+extern void xenoprof_log_event(struct vcpu *vcpu, struct pt_regs * regs,
                                unsigned long eip, int mode, int event);
 extern int is_active(struct domain *d);
 
@@ -55,7 +55,10 @@ xenoprof_handler(struct task_struct *tas
     if (!allow_virq || !allow_ints)
         return 0;
 
-    xenoprof_log_event(current, ip, xenoprofile_get_mode(task, regs), event);
+    // Note that log event actually expect cpu_user_regs, cast back 
+    // appropriately when doing the backtrace implementation in ia64
+    xenoprof_log_event(current, regs, ip, xenoprofile_get_mode(task, regs), 
+                                          event);
     
     // send VIRQ_XENOPROF
     if (is_active(current->domain) && !ring_0(regs))
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/x86/oprofile/Makefile
--- a/xen/arch/x86/oprofile/Makefile    Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/arch/x86/oprofile/Makefile    Thu Jun 07 14:30:21 2007 +0100
@@ -3,3 +3,4 @@ obj-y += op_model_p4.o
 obj-y += op_model_p4.o
 obj-y += op_model_ppro.o
 obj-y += op_model_athlon.o
+obj-y += backtrace.o
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/x86/oprofile/backtrace.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/oprofile/backtrace.c Thu Jun 07 14:30:21 2007 +0100
@@ -0,0 +1,132 @@
+/**
+ * @file backtrace.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon
+ * @author David Smith
+ * Modified for Xen by Amitabha Roy
+ *
+ */
+
+#include<xen/types.h>
+#include<asm/page.h>
+#include<xen/xenoprof.h>
+#include<asm/guest_access.h>
+
+struct frame_head {
+       struct frame_head * ebp;
+       unsigned long ret;
+} __attribute__((packed));
+
+static struct frame_head *
+dump_hypervisor_backtrace(struct domain *d, struct vcpu *vcpu, 
+                         struct frame_head * head, int mode)
+{
+       if (!xenoprof_add_trace(d, vcpu, head->ret, mode))
+               return 0;
+
+       /* frame pointers should strictly progress back up the stack
+        * (towards higher addresses) */
+       if (head >= head->ebp)
+               return NULL;
+
+       return head->ebp;
+}
+
+static struct frame_head *
+dump_guest_backtrace(struct domain *d, struct vcpu *vcpu, 
+                    struct frame_head * head, int mode)
+{
+       struct frame_head bufhead[2];
+       XEN_GUEST_HANDLE(char) guest_head = guest_handle_from_ptr(head, char);
+       
+       /* Also check accessibility of one struct frame_head beyond */
+       if (!guest_handle_okay(guest_head, sizeof(bufhead)))
+               return 0;
+       if (__copy_from_guest_offset((char *)bufhead, guest_head, 0, 
+           sizeof(bufhead)))
+               return 0;
+
+       if (!xenoprof_add_trace(d, vcpu, bufhead[0].ret, mode))
+           return 0;
+
+       /* frame pointers should strictly progress back up the stack
+        * (towards higher addresses) */
+       if (head >= bufhead[0].ebp)
+               return NULL;
+
+       return bufhead[0].ebp;
+}
+
+/*
+ * |             | /\ Higher addresses
+ * |             |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * .             .
+ * |    stack    |
+ * --------------- saved regs->ebp value if valid (frame_head address)
+ * .             .
+ * --------------- saved regs->rsp value if x86_64
+ * |             |
+ * --------------- struct pt_regs * stored on stack if 32-bit
+ * |             |
+ * .             .
+ * |             |
+ * --------------- %esp
+ * |             |
+ * |             | \/ Lower addresses
+ *
+ * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the
+ * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other
+ * exceptions use special stacks, maintained by the interrupt stack table
+ * (IST). These stacks are set up in trap_init() in
+ * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point
+ * to the kernel stack; instead, it points to some location on the NMI
+ * stack. On the other hand, regs->rsp is the stack pointer saved when the
+ * NMI occurred. (2) For 32-bit, regs->esp is not valid because the
+ * processor does not save %esp on the kernel stack when interrupts occur
+ * in the kernel mode.
+ */
+#if defined(CONFIG_FRAME_POINTER)
+static int valid_hypervisor_stack(struct frame_head * head, 
+                                 struct cpu_user_regs * regs)
+{
+       unsigned long headaddr = (unsigned long)head;
+#ifdef CONFIG_X86_64
+       unsigned long stack = (unsigned long)regs->rsp;
+#else
+       unsigned long stack = (unsigned long)regs;
+#endif
+       unsigned long stack_base = (stack & ~(STACK_SIZE - 1)) + STACK_SIZE;
+
+       return headaddr > stack && headaddr < stack_base;
+}
+#else
+/* without fp, it's just junk */
+static int valid_hypervisor_stack(struct frame_head * head, 
+                                 struct cpu_user_regs * regs)
+{
+       return 0;
+}
+#endif
+
+void xenoprof_backtrace(struct domain *d, struct vcpu *vcpu, 
+                       struct cpu_user_regs * const regs,
+                       unsigned long depth, int mode)
+{
+       struct frame_head *head;
+
+       head = (struct frame_head *)regs->ebp;
+
+       if (mode > 1) {
+               while (depth-- && valid_hypervisor_stack(head, regs))
+                   head = dump_hypervisor_backtrace(d, vcpu, head, mode);
+               return;
+       }
+
+       while (depth-- && head)
+           head = dump_guest_backtrace(d, vcpu, head, mode);
+}
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/x86/oprofile/op_model_athlon.c
--- a/xen/arch/x86/oprofile/op_model_athlon.c   Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/arch/x86/oprofile/op_model_athlon.c   Thu Jun 07 14:30:21 2007 +0100
@@ -43,8 +43,8 @@
 
 static unsigned long reset_value[NUM_COUNTERS];
 
-extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
-                              int mode, int event);
+extern void xenoprof_log_event(struct vcpu *v, struct cpu_user_regs * regs, 
+                              unsigned long eip, int mode, int event);
 extern int xenoprofile_get_mode(struct vcpu *v,
                                struct cpu_user_regs * const regs);
 
@@ -130,7 +130,7 @@ static int athlon_check_ctrs(unsigned in
        for (i = 0 ; i < NUM_COUNTERS; ++i) {
                CTR_READ(low, high, msrs, i);
                if (CTR_OVERFLOWED(low)) {
-                       xenoprof_log_event(current, eip, mode, i);
+                       xenoprof_log_event(current, regs, eip, mode, i);
                        CTR_WRITE(reset_value[i], msrs, i);
                        ovf = 1;
                }
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/x86/oprofile/op_model_p4.c
--- a/xen/arch/x86/oprofile/op_model_p4.c       Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/arch/x86/oprofile/op_model_p4.c       Thu Jun 07 14:30:21 2007 +0100
@@ -620,8 +620,8 @@ static void p4_setup_ctrs(struct op_msrs
        }
 }
 
-extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
-                              int mode, int event);
+extern void xenoprof_log_event(struct vcpu *v, struct cpu_user_regs * regs, 
+                              unsigned long eip, int mode, int event);
 extern int xenoprofile_get_mode(struct vcpu *v,
                                struct cpu_user_regs * const regs);
 
@@ -664,8 +664,8 @@ static int p4_check_ctrs(unsigned int co
                CCCR_READ(low, high, real);
                CTR_READ(ctr, high, real);
                if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
-                       xenoprof_log_event(current, eip, mode, i);
-                       CTR_WRITE(reset_value[i], real);
+                       xenoprof_log_event(current, regs, eip, mode, i);
+                       CTR_WRITE(reset_value[i], real);
                        CCCR_CLEAR_OVF(low);
                        CCCR_WRITE(low, high, real);
                        CTR_WRITE(reset_value[i], real);
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/x86/oprofile/op_model_ppro.c
--- a/xen/arch/x86/oprofile/op_model_ppro.c     Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/arch/x86/oprofile/op_model_ppro.c     Thu Jun 07 14:30:21 2007 +0100
@@ -88,8 +88,8 @@ static void ppro_setup_ctrs(struct op_ms
        }
 }
 
-extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
-                              int mode, int event);
+extern void xenoprof_log_event(struct vcpu *v, struct cpu_user_regs * regs, 
+                              unsigned long eip, int mode, int event);
 extern int xenoprofile_get_mode(struct vcpu *v,
                                struct cpu_user_regs * const regs);
  
@@ -106,7 +106,7 @@ static int ppro_check_ctrs(unsigned int 
        for (i = 0 ; i < NUM_COUNTERS; ++i) {
                CTR_READ(low, high, msrs, i);
                if (CTR_OVERFLOWED(low)) {
-                       xenoprof_log_event(current, eip, mode, i);
+                       xenoprof_log_event(current, regs, eip, mode, i);
                        CTR_WRITE(reset_value[i], msrs, i);
                        ovf = 1;
                }
diff -r 1cae82505e9e -r a7601de2f733 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/arch/x86/traps.c      Thu Jun 07 14:30:21 2007 +0100
@@ -167,7 +167,7 @@ static void show_guest_stack(struct cpu_
     printk("\n");
 }
 
-#ifdef NDEBUG
+#if !defined(CONFIG_FRAME_POINTER)
 
 static void show_trace(struct cpu_user_regs *regs)
 {
diff -r 1cae82505e9e -r a7601de2f733 xen/common/xenoprof.c
--- a/xen/common/xenoprof.c     Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/common/xenoprof.c     Thu Jun 07 14:30:21 2007 +0100
@@ -31,6 +31,7 @@ unsigned int activated;
 unsigned int activated;
 struct domain *xenoprof_primary_profiler;
 int xenoprof_state = XENOPROF_IDLE;
+static unsigned long backtrace_depth;
 
 u64 total_samples;
 u64 invalid_buffer_samples;
@@ -205,7 +206,8 @@ static int alloc_xenoprof_struct(
     i = 0;
     for_each_vcpu ( d, v )
     {
-        xenoprof_buf_t *buf = (xenoprof_buf_t *)&d->xenoprof->rawbuf[i * 
bufsize];
+        xenoprof_buf_t *buf = (xenoprof_buf_t *)
+            &d->xenoprof->rawbuf[i * bufsize];
 
         d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
         d->xenoprof->vcpu[v->vcpu_id].buffer = buf;
@@ -414,55 +416,36 @@ static int add_passive_list(XEN_GUEST_HA
     return ret;
 }
 
-void xenoprof_log_event(
-    struct vcpu *vcpu, unsigned long eip, int mode, int event)
-{
-    struct domain *d = vcpu->domain;
-    struct xenoprof_vcpu *v;
-    xenoprof_buf_t *buf;
-    int head;
-    int tail;
-    int size;
-
-
-    total_samples++;
-
-    /* ignore samples of un-monitored domains */
-    /* Count samples in idle separate from other unmonitored domains */
-    if ( !is_profiled(d) )
-    {
-        others_samples++;
-        return;
-    }
-
-    v = &d->xenoprof->vcpu[vcpu->vcpu_id];
-
-    /* Sanity check. Should never happen */ 
-    if ( v->buffer == NULL )
-    {
-        invalid_buffer_samples++;
-        return;
-    }
-
-    buf = v->buffer;
+
+/* Get space in the buffer */
+static int xenoprof_buf_space(struct domain *d, xenoprof_buf_t * buf, int size)
+{
+    int head, tail;
 
     head = xenoprof_buf(d, buf, event_head);
     tail = xenoprof_buf(d, buf, event_tail);
-    size = v->event_size;
-
+
+    return ((tail > head) ? 0 : size) + tail - head - 1;
+}
+
+/* Check for space and add a sample. Return 1 if successful, 0 otherwise. */
+static int xenoprof_add_sample(struct domain *d, xenoprof_buf_t *buf,
+                               unsigned long eip, int mode, int event)
+{
+    int head, tail, size;
+
+    head = xenoprof_buf(d, buf, event_head);
+    tail = xenoprof_buf(d, buf, event_tail);
+    size = xenoprof_buf(d, buf, event_size);
+    
     /* make sure indexes in shared buffer are sane */
     if ( (head < 0) || (head >= size) || (tail < 0) || (tail >= size) )
     {
         corrupted_buffer_samples++;
-        return;
-    }
-
-    if ( (head == tail - 1) || (head == size - 1 && tail == 0) )
-    {
-        xenoprof_buf(d, buf, lost_samples)++;
-        lost_samples++;
-    }
-    else
+        return 0;
+    }
+
+    if ( xenoprof_buf_space(d, buf, size) > 0 )
     {
         xenoprof_buf(d, buf, event_log[head].eip) = eip;
         xenoprof_buf(d, buf, event_log[head].mode) = mode;
@@ -470,7 +453,75 @@ void xenoprof_log_event(
         head++;
         if ( head >= size )
             head = 0;
+        
         xenoprof_buf(d, buf, event_head) = head;
+    }
+    else
+    {
+        xenoprof_buf(d, buf, lost_samples)++;
+        lost_samples++;
+        return 0;
+    }
+
+    return 1;
+}
+
+int xenoprof_add_trace(struct domain *d, struct vcpu *vcpu,
+                       unsigned long eip, int mode)
+{
+    xenoprof_buf_t *buf = d->xenoprof->vcpu[vcpu->vcpu_id].buffer;
+
+    /* Do not accidentally write an escape code due to a broken frame. */
+    if ( eip == XENOPROF_ESCAPE_CODE )
+    {
+        invalid_buffer_samples++;
+        return 0;
+    }
+
+    return xenoprof_add_sample(d, buf, eip, mode, 0);
+}
+
+void xenoprof_log_event(struct vcpu *vcpu, 
+                        struct cpu_user_regs * regs, unsigned long eip, 
+                        int mode, int event)
+{
+    struct domain *d = vcpu->domain;
+    struct xenoprof_vcpu *v;
+    xenoprof_buf_t *buf;
+
+    total_samples++;
+
+    /* Ignore samples of un-monitored domains. */
+    if ( !is_profiled(d) )
+    {
+        others_samples++;
+        return;
+    }
+
+    v = &d->xenoprof->vcpu[vcpu->vcpu_id];
+    if ( v->buffer == NULL )
+    {
+        invalid_buffer_samples++;
+        return;
+    }
+    
+    buf = v->buffer;
+
+    /* Provide backtrace if requested. */
+    if ( backtrace_depth > 0 )
+    {
+        if ( (xenoprof_buf_space(d, buf, v->event_size) < 2) ||
+             !xenoprof_add_sample(d, buf, XENOPROF_ESCAPE_CODE, mode, 
+                                  XENOPROF_TRACE_BEGIN) )
+        {
+            xenoprof_buf(d, buf, lost_samples)++;
+            lost_samples++;
+            return;
+        }
+    }
+
+    if ( xenoprof_add_sample(d, buf, eip, mode, event) )
+    {
         if ( is_active(vcpu->domain) )
             active_samples++;
         else
@@ -481,8 +532,14 @@ void xenoprof_log_event(
             xenoprof_buf(d, buf, kernel_samples)++;
         else
             xenoprof_buf(d, buf, xen_samples)++;
-    }
-}
+    
+    }
+
+    if ( backtrace_depth > 0 )
+        xenoprof_backtrace(d, vcpu, regs, backtrace_depth, mode);
+}
+
+
 
 static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
 {
@@ -685,7 +742,8 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         break;
 
     case XENOPROF_stop:
-        if ( xenoprof_state != XENOPROF_PROFILING ) {
+        if ( xenoprof_state != XENOPROF_PROFILING )
+        {
             ret = -EPERM;
             break;
         }
@@ -729,8 +787,17 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
             activated = 0;
             adomains=0;
             xenoprof_primary_profiler = NULL;
+            backtrace_depth=0;
             ret = 0;
         }
+        break;
+                
+    case XENOPROF_set_backtrace:
+        ret = 0;
+        if ( !xenoprof_backtrace_supported() )
+            ret = -EINVAL;
+        else if ( copy_from_guest(&backtrace_depth, arg, 1) )
+            ret = -EFAULT;
         break;
 
     default:
diff -r 1cae82505e9e -r a7601de2f733 xen/include/asm-ia64/xenoprof.h
--- a/xen/include/asm-ia64/xenoprof.h   Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/include/asm-ia64/xenoprof.h   Thu Jun 07 14:30:21 2007 +0100
@@ -37,7 +37,17 @@ struct vcpu;
 struct vcpu;
 struct cpu_user_regs;
 int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs);
-
+static inline int xenoprof_backtrace_supported(void)
+{
+    return 0;
+}
+static inline void xenoprof_backtrace(
+    struct domain *d, struct vcpu *vcpu, 
+    struct pt_regs *const regs, unsigned long depth, int mode)
+{
+    /* To be implemented */
+    return;
+}
 #define xenoprof_shared_gmfn(d, gmaddr, maddr)  \
     assign_domain_page((d), (gmaddr), (maddr));
 
diff -r 1cae82505e9e -r a7601de2f733 xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h    Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/include/asm-x86/xenoprof.h    Thu Jun 07 14:30:21 2007 +0100
@@ -46,7 +46,18 @@ int xenoprof_arch_counter(XEN_GUEST_HAND
 
 struct vcpu;
 struct cpu_user_regs;
+
 int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs);
+
+static inline int xenoprof_backtrace_supported(void)
+{
+    return 1;
+}
+
+void xenoprof_backtrace(
+    struct domain *d, struct vcpu *vcpu, 
+    struct cpu_user_regs *const regs, unsigned long depth, int mode);
+
 #define xenoprof_shared_gmfn(d, gmaddr, maddr)                      \
     do {                                                            \
         (void)(maddr);                                              \
diff -r 1cae82505e9e -r a7601de2f733 xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/include/public/xenoprof.h     Thu Jun 07 14:30:21 2007 +0100
@@ -49,7 +49,8 @@
 #define XENOPROF_release_counters   12
 #define XENOPROF_shutdown           13
 #define XENOPROF_get_buffer         14
-#define XENOPROF_last_op            14
+#define XENOPROF_set_backtrace      15
+#define XENOPROF_last_op            15
 
 #define MAX_OPROF_EVENTS    32
 #define MAX_OPROF_DOMAINS   25
@@ -61,6 +62,11 @@ struct event_log {
     uint8_t mode;
     uint8_t event;
 };
+
+/* PC value that indicates a special code */
+#define XENOPROF_ESCAPE_CODE ~0UL
+/* Transient events for the xenoprof->oprofile cpu buf */
+#define XENOPROF_TRACE_BEGIN 1
 
 /* Xenoprof buffer shared between Xen and domain - 1 per VCPU */
 struct xenoprof_buf {
diff -r 1cae82505e9e -r a7601de2f733 xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Thu Jun 07 11:15:24 2007 +0100
+++ b/xen/include/xen/xenoprof.h        Thu Jun 07 14:30:21 2007 +0100
@@ -66,6 +66,8 @@ void free_xenoprof_pages(struct domain *
 void free_xenoprof_pages(struct domain *d);
 
 int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg);
+int xenoprof_add_trace(struct domain *d, struct vcpu *v, 
+                       unsigned long eip, int mode);
 
 extern struct domain *xenoprof_primary_profiler;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.