WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Add backtrace support to xenoprof.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 11 Jun 2007 02:22:31 -0700
Delivery-date: Tue, 12 Jun 2007 05:06:45 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Add backtrace support to xenoprof., Xen patchbot-unstable <=