# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1ece34466781ec55f41fd29d53f6dafd208ba2fa
# Parent 98fcd017c5f357d25e1fe648784eb3d42d0c115d
Add new operation XENOPROF_get_buffer in xenoprof hypercall. Also
remove buffer related arguments from XENOPROF_init operation. This
is the first step to allow dynamic mapping/unmapping of xenoprof
buffers to
enable profiling a domain in passive mode and then switch to active
mode (or vice-versa). Currently a domain can only be profiled in a
single mode. Also passive domains cannot have oprofile builtin the
kernel or passive profiling will fail.
Signed-off-by: Jose Renato Santos <jsantos@xxxxxxxxxx>
---
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 91 ++++++++++++---------
xen/arch/x86/oprofile/xenoprof.c | 75 +++++++++--------
xen/include/public/xenoprof.h | 15 ++-
3 files changed, 105 insertions(+), 76 deletions(-)
diff -r 98fcd017c5f3 -r 1ece34466781
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Sep 13
14:01:23 2006 +0100
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Sep 13
14:05:33 2006 +0100
@@ -32,6 +32,8 @@
#include <../../../drivers/oprofile/cpu_buffer.h>
#include <../../../drivers/oprofile/event_buffer.h>
+#define MAX_XENOPROF_SAMPLES 16
+
static int xenoprof_start(void);
static void xenoprof_stop(void);
@@ -43,7 +45,7 @@ static int active_defined;
/* sample buffers shared with Xen */
xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
/* Shared buffer area */
-char * shared_buffer;
+char * shared_buffer = NULL;
/* Number of buffers in shared area (one per VCPU) */
int nbuf;
/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
@@ -233,13 +235,57 @@ static int bind_virq(void)
}
+static int map_xenoprof_buffer(int max_samples)
+{
+ struct xenoprof_get_buffer get_buffer;
+ struct xenoprof_buf *buf;
+ int npages, ret, i;
+ struct vm_struct *area;
+
+ if ( shared_buffer )
+ return 0;
+
+ get_buffer.max_samples = max_samples;
+
+ if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) )
+ return ret;
+
+ nbuf = get_buffer.nbuf;
+ npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1;
+
+ area = alloc_vm_area(npages * PAGE_SIZE);
+ if (area == NULL)
+ return -ENOMEM;
+
+ if ( (ret = direct_kernel_remap_pfn_range(
+ (unsigned long)area->addr,
+ get_buffer.buf_maddr >> PAGE_SHIFT,
+ npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF))
) {
+ vunmap(area->addr);
+ return ret;
+ }
+
+ shared_buffer = area->addr;
+ for (i=0; i< nbuf; i++) {
+ buf = (struct xenoprof_buf*)
+ &shared_buffer[i * get_buffer.bufsize];
+ BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
+ xenoprof_buf[buf->vcpu_id] = buf;
+ }
+
+ return 0;
+}
+
+
static int xenoprof_setup(void)
{
int ret;
int i;
- ret = bind_virq();
- if (ret)
+ if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
+ return ret;
+
+ if ( (ret = bind_virq()) )
return ret;
if (is_primary) {
@@ -482,50 +528,18 @@ int __init oprofile_arch_init(struct opr
int __init oprofile_arch_init(struct oprofile_operations * ops)
{
struct xenoprof_init init;
- struct xenoprof_buf *buf;
- int npages, ret, i;
- struct vm_struct *area;
-
- init.max_samples = 16;
+ int ret, i;
+
ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
if (!ret) {
- pgprot_t prot = __pgprot(_KERNPG_TABLE);
-
num_events = init.num_events;
is_primary = init.is_primary;
- nbuf = init.nbuf;
/* just in case - make sure we do not overflow event list
- (i.e. counter_config list) */
+ (i.e. counter_config list) */
if (num_events > OP_MAX_COUNTER)
num_events = OP_MAX_COUNTER;
-
- npages = (init.bufsize * nbuf - 1) / PAGE_SIZE + 1;
-
- area = alloc_vm_area(npages * PAGE_SIZE);
- if (area == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = direct_kernel_remap_pfn_range(
- (unsigned long)area->addr,
- init.buf_maddr >> PAGE_SHIFT,
- npages * PAGE_SIZE, prot, DOMID_SELF);
- if (ret) {
- vunmap(area->addr);
- goto out;
- }
-
- shared_buffer = area->addr;
-
- for (i=0; i< nbuf; i++) {
- buf = (struct xenoprof_buf*)
- &shared_buffer[i * init.bufsize];
- BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
- xenoprof_buf[buf->vcpu_id] = buf;
- }
/* cpu_type is detected by Xen */
cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
@@ -541,7 +555,6 @@ int __init oprofile_arch_init(struct opr
active_defined = 0;
}
- out:
printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, "
"is_primary %d\n", ret, num_events, is_primary);
return ret;
diff -r 98fcd017c5f3 -r 1ece34466781 xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c Wed Sep 13 14:01:23 2006 +0100
+++ b/xen/arch/x86/oprofile/xenoprof.c Wed Sep 13 14:05:33 2006 +0100
@@ -437,54 +437,59 @@ int xenoprof_op_init(XEN_GUEST_HANDLE(vo
int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_init xenoprof_init;
- int is_primary, num_events;
+ int ret;
+
+ if ( copy_from_guest(&xenoprof_init, arg, 1) )
+ return -EFAULT;
+
+ if ( (ret = nmi_init(&xenoprof_init.num_events,
+ &xenoprof_init.is_primary,
+ xenoprof_init.cpu_type)) )
+ return ret;
+
+ if ( copy_to_guest(arg, &xenoprof_init, 1) )
+ return -EFAULT;
+
+ if ( xenoprof_init.is_primary )
+ primary_profiler = current->domain;
+
+ return 0;
+}
+
+int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
+{
+ struct xenoprof_get_buffer xenoprof_get_buffer;
struct domain *d = current->domain;
int ret;
- if ( copy_from_guest(&xenoprof_init, arg, 1) )
+ if ( copy_from_guest(&xenoprof_get_buffer, arg, 1) )
return -EFAULT;
- ret = nmi_init(&num_events,
- &is_primary,
- xenoprof_init.cpu_type);
- if ( ret < 0 )
- goto err;
-
- if ( is_primary )
- primary_profiler = current->domain;
-
/*
- * We allocate xenoprof struct and buffers only at first time xenoprof_init
+ * We allocate xenoprof struct and buffers only at first time
xenoprof_get_buffer
* is called. Memory is then kept until domain is destroyed.
*/
if ( (d->xenoprof == NULL) &&
- ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples, 0)) < 0) )
- goto err;
+ ((ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0))
< 0) )
+ return ret;
xenoprof_reset_buf(d);
d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
d->xenoprof->domain_ready = 0;
- d->xenoprof->is_primary = is_primary;
-
- xenoprof_init.is_primary = is_primary;
- xenoprof_init.num_events = num_events;
- xenoprof_init.nbuf = d->xenoprof->nbuf;
- xenoprof_init.bufsize = d->xenoprof->bufsize;
- xenoprof_init.buf_maddr = __pa(d->xenoprof->rawbuf);
-
- if ( copy_to_guest(arg, &xenoprof_init, 1) )
- {
- ret = -EFAULT;
- goto err;
- }
-
- return ret;
-
- err:
if ( primary_profiler == current->domain )
- primary_profiler = NULL;
- return ret;
+ d->xenoprof->is_primary = 1;
+ else
+ d->xenoprof->is_primary = 0;
+
+ xenoprof_get_buffer.nbuf = d->xenoprof->nbuf;
+ xenoprof_get_buffer.bufsize = d->xenoprof->bufsize;
+ xenoprof_get_buffer.buf_maddr = __pa(d->xenoprof->rawbuf);
+
+ if ( copy_to_guest(arg, &xenoprof_get_buffer, 1) )
+ return -EFAULT;
+
+ return 0;
}
#define PRIV_OP(op) ( (op == XENOPROF_set_active) \
@@ -510,6 +515,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
{
case XENOPROF_init:
ret = xenoprof_op_init(arg);
+ break;
+
+ case XENOPROF_get_buffer:
+ ret = xenoprof_op_get_buffer(arg);
break;
case XENOPROF_reset_active_list:
diff -r 98fcd017c5f3 -r 1ece34466781 xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h Wed Sep 13 14:01:23 2006 +0100
+++ b/xen/include/public/xenoprof.h Wed Sep 13 14:05:33 2006 +0100
@@ -28,6 +28,8 @@
#define XENOPROF_disable_virq 11
#define XENOPROF_release_counters 12
#define XENOPROF_shutdown 13
+#define XENOPROF_get_buffer 14
+#define XENOPROF_last_op 14
#define MAX_OPROF_EVENTS 32
#define MAX_OPROF_DOMAINS 25
@@ -56,16 +58,21 @@ DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);
DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);
struct xenoprof_init {
- int32_t max_samples;
int32_t num_events;
int32_t is_primary;
- int32_t nbuf;
- int32_t bufsize;
- uint64_t buf_maddr;
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
};
typedef struct xenoprof_init xenoprof_init_t;
DEFINE_XEN_GUEST_HANDLE(xenoprof_init_t);
+
+struct xenoprof_get_buffer {
+ int32_t max_samples;
+ int32_t nbuf;
+ int32_t bufsize;
+ uint64_t buf_maddr;
+};
+typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
+DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
struct xenoprof_counter {
uint32_t ind;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|