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

[Xen-changelog] [xen-unstable] [XENOPROFILE] Make xenoprof arch-generic with dynamic mapping/unmapping xenoprof



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 1d7d5d48fcdc2e73ce63e3aa8f6959e3669f9123
# Parent  1ef9954a26686b35b946d889726d4d35c283c2a0
[XENOPROFILE] Make xenoprof arch-generic with dynamic mapping/unmapping xenoprof
buffer support and auto translated mode support.
renamed xenoprof_get_buffer::buf_maddr, xenoprof_passive::buf_maddr to
xenoprof_get_buffer::buf_gmaddr, xenoprof_passive::buf_gmaddr
to support auto translated mode. With auto translated mode enabled,
it is gmaddr, not maddr.

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>

Simplify the share function.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c |    4 
 xen/arch/x86/oprofile/nmi_int.c                    |    5 
 xen/common/xenoprof.c                              |  122 +++++++++++++++------
 xen/include/asm-x86/xenoprof.h                     |   11 +
 xen/include/public/xenoprof.h                      |    4 
 xen/include/xen/xenoprof.h                         |    4 
 6 files changed, 113 insertions(+), 37 deletions(-)

diff -r 1ef9954a2668 -r 1d7d5d48fcdc 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Wed Nov 22 
09:51:20 2006 +0000
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Wed Nov 22 
10:09:28 2006 +0000
@@ -93,7 +93,7 @@ int xenoprof_arch_map_shared_buffer(stru
 
        if ( (ret = direct_kernel_remap_pfn_range(
                      (unsigned long)area->addr,
-                     get_buffer->buf_maddr >> PAGE_SHIFT,
+                     get_buffer->buf_gmaddr >> PAGE_SHIFT,
                      npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE),
                      DOMID_SELF)) ) {
                vunmap(area->addr);
@@ -127,7 +127,7 @@ int xenoprof_arch_set_passive(struct xen
 
        ret = direct_kernel_remap_pfn_range(
                (unsigned long)area->addr,
-               pdomain->buf_maddr >> PAGE_SHIFT,
+               pdomain->buf_gmaddr >> PAGE_SHIFT,
                npages * PAGE_SIZE, prot, DOMID_SELF);
        if (ret) {
                vunmap(area->addr);
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/arch/x86/oprofile/nmi_int.c   Wed Nov 22 10:09:28 2006 +0000
@@ -33,7 +33,6 @@ static unsigned long saved_lvtpc[NR_CPUS
 #define VIRQ_BITMASK_SIZE (MAX_OPROF_DOMAINS/32 + 1)
 extern int active_domains[MAX_OPROF_DOMAINS];
 extern unsigned int adomains;
-extern struct domain *primary_profiler;
 extern struct domain *adomain_ptrs[MAX_OPROF_DOMAINS];
 extern unsigned long virq_ovf_pending[VIRQ_BITMASK_SIZE];
 extern int is_active(struct domain *d);
@@ -339,10 +338,10 @@ int nmi_init(int *num_events, int *is_pr
                return -ENODEV;
        }
 
-       if (primary_profiler == NULL) {
+       if (xenoprof_primary_profiler == NULL) {
                /* For now, only dom0 can be the primary profiler */
                if (current->domain->domain_id == 0) {
-                       primary_profiler = current->domain;
+                       xenoprof_primary_profiler = current->domain;
                        prim = 1;
                }
        }
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/common/xenoprof.c
--- a/xen/common/xenoprof.c     Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/common/xenoprof.c     Wed Nov 22 10:09:28 2006 +0000
@@ -2,15 +2,17 @@
  * Copyright (C) 2005 Hewlett-Packard Co.
  * written by Aravind Menon & Jose Renato Santos
  *            (email: xenoprof@xxxxxxxxxxxxx)
+ *
+ * arch generic xenoprof and IA64 support.
+ * dynamic map/unmap xenoprof buffer support.
  * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
  *                    VA Linux Systems Japan K.K.
- * arch generic xenoprof and IA64 support.
  */
 
 #include <xen/guest_access.h>
 #include <xen/sched.h>
 #include <public/xenoprof.h>
-#include <asm/hvm/support.h>
+#include <asm/shadow.h>
 
 /* Limit amount of pages used for shared buffer (per domain) */
 #define MAX_OPROF_SHARED_PAGES 32
@@ -26,7 +28,7 @@ unsigned int pdomains;
 unsigned int pdomains;
 
 unsigned int activated;
-struct domain *primary_profiler;
+struct domain *xenoprof_primary_profiler;
 int xenoprof_state = XENOPROF_IDLE;
 
 u64 total_samples;
@@ -90,10 +92,46 @@ static void xenoprof_reset_buf(struct do
     }
 }
 
-static char *alloc_xenoprof_buf(struct domain *d, int npages)
+static void
+share_xenoprof_page_with_guest(struct domain* d, unsigned long mfn, int npages)
+{
+    int i;
+    
+    for ( i = 0; i < npages; i++ )
+        share_xen_page_with_guest(mfn_to_page(mfn + i), d, XENSHARE_writable);
+}
+
+static void
+unshare_xenoprof_page_with_guest(unsigned long mfn, int npages)
+{
+    int i;
+
+    for ( i = 0; i < npages; i++ )
+    {
+        struct page_info *page = mfn_to_page(mfn + i);
+        BUG_ON(page_get_owner(page) != current->domain);
+        if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
+            put_page(page);
+    }
+}
+
+static void
+xenoprof_shared_gmfn_with_guest(
+    struct domain* d, unsigned long maddr, unsigned long gmaddr, int npages)
+{
+    int i;
+    
+    for ( i = 0; i < npages; i++, maddr += PAGE_SIZE, gmaddr += PAGE_SIZE )
+    {
+        BUG_ON(page_get_owner(maddr_to_page(maddr)) != d);
+        xenoprof_shared_gmfn(d, gmaddr, maddr);
+    }
+}
+
+static char *alloc_xenoprof_buf(struct domain *d, int npages, uint64_t gmaddr)
 {
     char *rawbuf;
-    int i, order;
+    int order;
 
     /* allocate pages to store sample buffer shared with domain */
     order  = get_order_from_pages(npages);
@@ -104,17 +142,11 @@ static char *alloc_xenoprof_buf(struct d
         return 0;
     }
 
-    /* Share pages so that kernel can map it */
-    for ( i = 0; i < npages; i++ )
-        share_xen_page_with_guest(
-            virt_to_page(rawbuf + i * PAGE_SIZE), 
-            d, XENSHARE_writable);
-
     return rawbuf;
 }
 
 static int alloc_xenoprof_struct(
-    struct domain *d, int max_samples, int is_passive)
+    struct domain *d, int max_samples, int is_passive, uint64_t gmaddr)
 {
     struct vcpu *v;
     int nvcpu, npages, bufsize, max_bufsize;
@@ -147,7 +179,8 @@ static int alloc_xenoprof_struct(
         (max_samples - 1) * sizeof(struct event_log);
     npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
     
-    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages);
+    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages,
+                                             gmaddr);
 
     if ( d->xenoprof->rawbuf == NULL )
     {
@@ -269,6 +302,7 @@ static void reset_passive(struct domain 
     if ( x == NULL )
         return;
 
+    unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
     x->domain_type = XENOPROF_DOMAIN_IGNORED;
 }
 
@@ -332,17 +366,30 @@ static int add_passive_list(XEN_GUEST_HA
     if ( d == NULL )
         return -EINVAL;
 
-    if ( (d->xenoprof == NULL) && 
-         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) )
-    {
-        put_domain(d);
-        return -ENOMEM;
-    }
+    if ( d->xenoprof == NULL )
+    {
+        ret = alloc_xenoprof_struct(
+            d, passive.max_samples, 1, passive.buf_gmaddr);
+        if ( ret < 0 )
+        {
+            put_domain(d);
+            return -ENOMEM;
+        }
+    }
+
+    share_xenoprof_page_with_guest(
+        current->domain, virt_to_mfn(d->xenoprof->rawbuf),
+        d->xenoprof->npages);
 
     d->xenoprof->domain_type = XENOPROF_DOMAIN_PASSIVE;
     passive.nbuf = d->xenoprof->nbuf;
     passive.bufsize = d->xenoprof->bufsize;
-    passive.buf_maddr = __pa(d->xenoprof->rawbuf);
+    if ( !shadow_mode_translate(d) )
+        passive.buf_gmaddr = __pa(d->xenoprof->rawbuf);
+    else
+        xenoprof_shared_gmfn_with_guest(
+            current->domain, __pa(d->xenoprof->rawbuf),
+            passive.buf_gmaddr, d->xenoprof->npages);
 
     if ( copy_to_guest(arg, &passive, 1) )
     {
@@ -442,7 +489,7 @@ static int xenoprof_op_init(XEN_GUEST_HA
         return -EFAULT;
 
     if ( xenoprof_init.is_primary )
-        primary_profiler = current->domain;
+        xenoprof_primary_profiler = current->domain;
 
     return 0;
 }
@@ -462,20 +509,30 @@ static int xenoprof_op_get_buffer(XEN_GU
      */
     if ( d->xenoprof == NULL )
     {
-        ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0);
+        ret = alloc_xenoprof_struct(
+            d, xenoprof_get_buffer.max_samples, 0,
+            xenoprof_get_buffer.buf_gmaddr);
         if ( ret < 0 )
             return ret;
     }
 
+    share_xenoprof_page_with_guest(
+        d, virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages);
+
     xenoprof_reset_buf(d);
 
     d->xenoprof->domain_type  = XENOPROF_DOMAIN_IGNORED;
     d->xenoprof->domain_ready = 0;
-    d->xenoprof->is_primary   = (primary_profiler == current->domain);
+    d->xenoprof->is_primary   = (xenoprof_primary_profiler == current->domain);
         
     xenoprof_get_buffer.nbuf = d->xenoprof->nbuf;
     xenoprof_get_buffer.bufsize = d->xenoprof->bufsize;
-    xenoprof_get_buffer.buf_maddr = __pa(d->xenoprof->rawbuf);
+    if ( !shadow_mode_translate(d) )
+        xenoprof_get_buffer.buf_gmaddr = __pa(d->xenoprof->rawbuf);
+    else
+        xenoprof_shared_gmfn_with_guest(
+            d, __pa(d->xenoprof->rawbuf), xenoprof_get_buffer.buf_gmaddr,
+            d->xenoprof->npages);
 
     if ( copy_to_guest(arg, &xenoprof_get_buffer, 1) )
         return -EFAULT;
@@ -499,7 +556,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         return -EINVAL;
     }
 
-    if ( !NONPRIV_OP(op) && (current->domain != primary_profiler) )
+    if ( !NONPRIV_OP(op) && (current->domain != xenoprof_primary_profiler) )
     {
         printk("xenoprof: dom %d denied privileged operation %d\n",
                current->domain->domain_id, op);
@@ -592,7 +649,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
     case XENOPROF_enable_virq:
     {
         int i;
-        if ( current->domain == primary_profiler )
+        if ( current->domain == xenoprof_primary_profiler )
         {
             xenoprof_arch_enable_virq();
             xenoprof_reset_stat();
@@ -609,7 +666,6 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         if ( (xenoprof_state == XENOPROF_READY) &&
              (activated == adomains) )
             ret = xenoprof_arch_start();
-
         if ( ret == 0 )
             xenoprof_state = XENOPROF_PROFILING;
         break;
@@ -624,14 +680,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         break;
 
     case XENOPROF_disable_virq:
+    {
+        struct xenoprof *x;
         if ( (xenoprof_state == XENOPROF_PROFILING) && 
              (is_active(current->domain)) )
         {
             ret = -EPERM;
             break;
         }
-        ret = reset_active(current->domain);
-        break;
+        if ( (ret = reset_active(current->domain)) != 0 )
+            break;
+        x = current->domain->xenoprof;
+        unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
+        break;
+    }
 
     case XENOPROF_release_counters:
         ret = -EPERM;
@@ -652,7 +714,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         {
             activated = 0;
             adomains=0;
-            primary_profiler = NULL;
+            xenoprof_primary_profiler = NULL;
             ret = 0;
         }
         break;
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h    Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/include/asm-x86/xenoprof.h    Wed Nov 22 10:09:28 2006 +0000
@@ -44,6 +44,17 @@ void nmi_release_counters(void);
 
 int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
 
+struct vcpu;
+struct cpu_user_regs;
+int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs);
+#define xenoprof_shared_gmfn(d, gmaddr, maddr)                      \
+    do {                                                            \
+        (void)(maddr);                                              \
+        gdprintk(XENLOG_WARNING,                                    \
+                 "xenoprof/x86 with autotranslated mode enabled"    \
+                 "isn't supported yet\n");                          \
+    } while (0)
+
 #endif /* __ASM_X86_XENOPROF_H__ */
 
 /*
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/include/public/xenoprof.h     Wed Nov 22 10:09:28 2006 +0000
@@ -87,7 +87,7 @@ struct xenoprof_get_buffer {
     int32_t  max_samples;
     int32_t  nbuf;
     int32_t  bufsize;
-    uint64_t buf_maddr;
+    uint64_t buf_gmaddr;
 };
 typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
 DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
@@ -110,7 +110,7 @@ typedef struct xenoprof_passive {
     int32_t  max_samples;
     int32_t  nbuf;
     int32_t  bufsize;
-    uint64_t buf_maddr;
+    uint64_t buf_gmaddr;
 } xenoprof_passive_t;
 DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
 
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/include/xen/xenoprof.h        Wed Nov 22 10:09:28 2006 +0000
@@ -41,4 +41,8 @@ struct domain;
 struct domain;
 void free_xenoprof_pages(struct domain *d);
 
+int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg);
+
+extern struct domain *xenoprof_primary_profiler;
+
 #endif  /* __XEN__XENOPROF_H__ */

_______________________________________________
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®.