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

[Xen-devel] [PATCH 5/5 TAKE 2] xenoprof: make xen xenoprof code arch-generic



# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Date 1163486063 -32400
# Node ID 236b3f5ec6bfef2971864dd7bb16f286e5e83a83
# Parent  3bebc37b149280f5ff1e6091d578c7da73820f16
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.
PATCHNAME: make_xenoprof_of_xen_side_arch_generic

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

diff -r 3bebc37b1492 -r 236b3f5ec6bf 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Tue Nov 14 
15:34:22 2006 +0900
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Tue Nov 14 
15:34:23 2006 +0900
@@ -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 3bebc37b1492 -r 236b3f5ec6bf xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/arch/x86/oprofile/nmi_int.c   Tue Nov 14 15:34:23 2006 +0900
@@ -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);
@@ -337,10 +336,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 3bebc37b1492 -r 236b3f5ec6bf xen/common/xenoprof.c
--- a/xen/common/xenoprof.c     Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/common/xenoprof.c     Tue Nov 14 15:34:23 2006 +0900
@@ -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,58 @@ static void xenoprof_reset_buf(struct do
     }
 }
 
-static char *alloc_xenoprof_buf(struct domain *d, int npages)
+static int
+share_xenoprof_page_with_guest(struct domain* d, unsigned long mfn, int npages)
+{
+    int i;
+    
+    /* Share pages so that kernel can map it */
+    for (i = 0; i < npages; i++) {
+        struct page_info* page = mfn_to_page(mfn + i);
+        if ((page->count_info & (PGC_allocated|PGC_count_mask)) != 0) {
+            gdprintk(XENLOG_INFO, "%s: mfn 0x%lx page->count_info 0x%x\n",
+                     __func__, mfn + i, page->count_info);
+            return -EBUSY;
+        }
+        page->count_info = 0;
+        page_set_owner(page, NULL);
+    }
+
+    for (i = 0; i < npages; i++)
+        share_xen_page_with_guest(mfn_to_page(mfn + i), d, XENSHARE_writable);
+    return 0;
+}
+
+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 +154,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 +191,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 +314,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;
 
     return;
@@ -339,15 +385,26 @@ static int add_passive_list(XEN_GUEST_HA
         return -EINVAL;
 
     if ( (d->xenoprof == NULL) && 
-         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) {
+         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1,
+                                       passive.buf_gmaddr)) < 0) ) {
         put_domain(d);
         return -ENOMEM;
+    }
+
+    ret = share_xenoprof_page_with_guest(current->domain,
+                virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages);
+    if (ret) {
+        put_domain(d);
+        return ret;
     }
 
     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) ) {
         put_domain(d);
@@ -446,7 +503,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;
 }
@@ -465,21 +522,32 @@ static int xenoprof_op_get_buffer(XEN_GU
      * is called. Memory is then kept until domain is destroyed.
      */
     if ( (d->xenoprof == NULL) &&
-         ((ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0)) 
< 0) )
+         ((ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0,
+                                       xenoprof_get_buffer.buf_gmaddr)) < 0) )
+        return ret;
+
+    ret = share_xenoprof_page_with_guest(d, virt_to_mfn(d->xenoprof->rawbuf),
+                                         d->xenoprof->npages);
+    if (ret)
         return ret;
 
     xenoprof_reset_buf(d);
 
     d->xenoprof->domain_type  = XENOPROF_DOMAIN_IGNORED;
     d->xenoprof->domain_ready = 0;
-    if ( primary_profiler == current->domain )
+    if ( xenoprof_primary_profiler == current->domain )
         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 (!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;
@@ -503,7 +571,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);
@@ -589,7 +657,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();
@@ -607,7 +675,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;
@@ -622,14 +689,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         break;
 
     case XENOPROF_disable_virq:
+    {
+        struct xenoprof *x = current->domain->xenoprof;
         if ( (xenoprof_state == XENOPROF_PROFILING) && 
              (is_active(current->domain)) ) {
             ret = -EPERM;
             break;
         }
         ret = reset_active(current->domain);
-        break;
-
+        if (ret)
+            break;
+        x = current->domain->xenoprof; /*reset_active() guarantees x != NULL*/
+        unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
+        break;
+    }
     case XENOPROF_release_counters:
         ret = -EPERM;
         if ( (xenoprof_state == XENOPROF_COUNTERS_RESERVED) ||
@@ -649,7 +722,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 3bebc37b1492 -r 236b3f5ec6bf xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h    Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/include/asm-x86/xenoprof.h    Tue Nov 14 15:34:23 2006 +0900
@@ -45,6 +45,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_ERR,                                        \
+                 "xenoprof/x86 with autotranslated mode enabled"    \
+                 "isn't supported yet\n");                          \
+    } while (0)
+
 #endif /* __ASM_XENOPROF_H__ */
 
 /*
diff -r 3bebc37b1492 -r 236b3f5ec6bf xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/include/public/xenoprof.h     Tue Nov 14 15:34:23 2006 +0900
@@ -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 3bebc37b1492 -r 236b3f5ec6bf xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/include/xen/xenoprof.h        Tue Nov 14 15:34:23 2006 +0900
@@ -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__ */
yamahata

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.