From: kfraser Date: Thu, 7 Jun 2007 12:48:27 +0000 (+0100) Subject: Add backtrace support to xenoprof. X-Git-Tag: xen-3.2.0~219 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=6648568fc464daa971aa87c3f2b4186fc024c42c;p=legacy%2Flinux-2.6.18-xen.git Add backtrace support to xenoprof. Signed-off-by: Amitabha Roy Reviewed-by: Jose Renato G Santos --- diff --git a/drivers/xen/xenoprof/xenoprofile.c b/drivers/xen/xenoprof/xenoprofile.c index 382a50f6..37097f84 100644 --- a/drivers/xen/xenoprof/xenoprofile.c +++ b/drivers/xen/xenoprof/xenoprofile.c @@ -51,11 +51,13 @@ static int xenoprof_enabled = 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 long long p_oprofile_samples = 0; 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++; + + } 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 = 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++; 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_domains, 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,9 +466,23 @@ 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 .create_files = 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 oprofile_operations * ops) 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;