# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1181220507 -3600
# Node ID 56b6e11f15fe2db18c5d4992124a273c781d894b
# Parent 85b046c1da186089a6069b4d0f879ea7c32c4c42
Add backtrace support to xenoprof.
Signed-off-by: Amitabha Roy <amitabha.roy@xxxxxxxxx>
Reviewed-by: Jose Renato G Santos <joserenato.santos@xxxxxx>
---
drivers/xen/xenoprof/xenoprofile.c | 102 ++++++++++++++++++++++++++-----------
1 files changed, 73 insertions(+), 29 deletions(-)
diff -r 85b046c1da18 -r 56b6e11f15fe drivers/xen/xenoprof/xenoprofile.c
--- a/drivers/xen/xenoprof/xenoprofile.c Thu Jun 07 11:11:13 2007 +0100
+++ b/drivers/xen/xenoprof/xenoprofile.c Thu Jun 07 13:48:27 2007 +0100
@@ -51,11 +51,13 @@ static int xenoprof_is_primary = 0;
static int xenoprof_is_primary = 0;
static int active_defined;
+extern unsigned long backtrace_depth;
+
/* Number of buffers in shared area (one per VCPU) */
int nbuf;
/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
int ovf_irq[NR_CPUS];
-/* cpu model type string - copied from Xen memory space on XENOPROF_init
command */
+/* cpu model type string - copied from Xen on XENOPROF_init command */
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
#ifdef CONFIG_PM
@@ -115,38 +117,54 @@ unsigned int pdomains;
unsigned int pdomains;
struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
+/* Check whether the given entry is an escape code */
+static int xenoprof_is_escape(xenoprof_buf_t * buf, int tail)
+{
+ return (buf->event_log[tail].eip == XENOPROF_ESCAPE_CODE);
+}
+
+/* Get the event at the given entry */
+static uint8_t xenoprof_get_event(xenoprof_buf_t * buf, int tail)
+{
+ return (buf->event_log[tail].event);
+}
+
static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
{
int head, tail, size;
+ int tracing = 0;
head = buf->event_head;
tail = buf->event_tail;
size = buf->event_size;
- if (tail > head) {
- while (tail < size) {
- oprofile_add_pc(buf->event_log[tail].eip,
- buf->event_log[tail].mode,
- buf->event_log[tail].event);
+ while (tail != head) {
+ if (xenoprof_is_escape(buf, tail) &&
+ xenoprof_get_event(buf, tail) == XENOPROF_TRACE_BEGIN) {
+ tracing=1;
+ oprofile_add_pc(ESCAPE_CODE, buf->event_log[tail].mode,
+ CPU_TRACE_BEGIN);
if (!is_passive)
oprofile_samples++;
else
p_oprofile_samples++;
- tail++;
- }
- tail = 0;
- }
- while (tail < head) {
- oprofile_add_pc(buf->event_log[tail].eip,
- buf->event_log[tail].mode,
- buf->event_log[tail].event);
- if (!is_passive)
- oprofile_samples++;
- else
- p_oprofile_samples++;
+
+ } else {
+ oprofile_add_pc(buf->event_log[tail].eip,
+ buf->event_log[tail].mode,
+ buf->event_log[tail].event);
+ if (!tracing) {
+ if (!is_passive)
+ oprofile_samples++;
+ else
+ p_oprofile_samples++;
+ }
+
+ }
tail++;
- }
-
+ if(tail==size)
+ tail=0;
+ }
buf->event_tail = tail;
}
@@ -162,8 +180,8 @@ static void xenoprof_handle_passive(void
if (buf->event_head == buf->event_tail)
continue;
if (!flag_domain) {
- if
(!oprofile_add_domain_switch(passive_domains[i].
- domain_id))
+ if (!oprofile_add_domain_switch(
+ passive_domains[i].domain_id))
goto done;
flag_domain = 1;
}
@@ -284,22 +302,31 @@ static int xenoprof_setup(void)
/* Define dom0 as an active domain if not done yet */
if (!active_defined) {
domid_t domid;
- ret =
HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
+ ret = HYPERVISOR_xenoprof_op(
+ XENOPROF_reset_active_list, NULL);
if (ret)
goto err;
domid = 0;
- ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active,
&domid);
+ ret = HYPERVISOR_xenoprof_op(
+ XENOPROF_set_active, &domid);
if (ret)
goto err;
active_defined = 1;
}
+ if (backtrace_depth > 0) {
+ ret = HYPERVISOR_xenoprof_op(XENOPROF_set_backtrace,
+ &backtrace_depth);
+ if (ret)
+ backtrace_depth = 0;
+ }
+
ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL);
if (ret)
goto err;
+
xenoprof_arch_counter();
ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events, NULL);
-
if (ret)
goto err;
}
@@ -425,7 +452,8 @@ static int xenoprof_set_passive(int * p_
goto out;
for (j = 0; j < passive_domains[i].nbuf; j++) {
buf = (struct xenoprof_buf *)
- &p_shared_buffer[i].buffer[j *
passive_domains[i].bufsize];
+ &p_shared_buffer[i].buffer[
+ j * passive_domains[i].bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
p_xenoprof_buf[i][buf->vcpu_id] = buf;
}
@@ -438,8 +466,22 @@ out:
for (j = 0; j < i; j++)
xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
- return ret;
-}
+ return ret;
+}
+
+
+/* The dummy backtrace function to keep oprofile happy
+ * The real backtrace is done in xen
+ */
+static void xenoprof_dummy_backtrace(struct pt_regs * const regs,
+ unsigned int depth)
+{
+ /* this should never be called */
+ BUG();
+ return;
+}
+
+
struct oprofile_operations xenoprof_ops = {
#ifdef HAVE_XENOPROF_CREATE_FILES
@@ -450,7 +492,8 @@ struct oprofile_operations xenoprof_ops
.setup = xenoprof_setup,
.shutdown = xenoprof_shutdown,
.start = xenoprof_start,
- .stop = xenoprof_stop
+ .stop = xenoprof_stop,
+ .backtrace = xenoprof_dummy_backtrace
};
@@ -481,6 +524,7 @@ int __init xenoprofile_init(struct oprof
active_defined = 0;
}
+
printk(KERN_INFO "%s: ret %d, events %d, xenoprof_is_primary %d\n",
__func__, ret, init.num_events, xenoprof_is_primary);
return ret;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|