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

[Xen-changelog] [xen-unstable] Change DOM0_PERFCCONTROL: remove array limit.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 7924b6bd728a3192ed5ff1792499273862a183e5
# Parent  47af0e2ebb1369e36c203ee10246ff3a79255b23
Change DOM0_PERFCCONTROL: remove array limit.

Descriptors and values are passed by two distinct buffers.

Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx>
---
 tools/libxc/xc_misc.c         |   13 +++++++--
 tools/libxc/xenctrl.h         |    9 ++++--
 tools/misc/xenperf.c          |   60 ++++++++++++++++++++++++------------------
 xen/common/perfc.c            |   41 +++++++++++++++++-----------
 xen/include/public/dom0_ops.h |    7 +++-
 5 files changed, 83 insertions(+), 47 deletions(-)

diff -r 47af0e2ebb13 -r 7924b6bd728a tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c     Mon Aug 07 15:42:25 2006 +0100
+++ b/tools/libxc/xc_misc.c     Mon Aug 07 15:53:06 2006 +0100
@@ -68,7 +68,10 @@ int xc_sched_id(int xc_handle,
 
 int xc_perfc_control(int xc_handle,
                      uint32_t opcode,
-                     xc_perfc_desc_t *desc)
+                     xc_perfc_desc_t *desc,
+                     xc_perfc_val_t *val,
+                     int *nbr_desc,
+                     int *nbr_val)
 {
     int rc;
     DECLARE_DOM0_OP;
@@ -76,10 +79,16 @@ int xc_perfc_control(int xc_handle,
     op.cmd = DOM0_PERFCCONTROL;
     op.u.perfccontrol.op   = opcode;
     set_xen_guest_handle(op.u.perfccontrol.desc, desc);
+    set_xen_guest_handle(op.u.perfccontrol.val, val);
 
     rc = do_dom0_op(xc_handle, &op);
 
-    return (rc == 0) ? op.u.perfccontrol.nr_counters : rc;
+    if (nbr_desc)
+        *nbr_desc = op.u.perfccontrol.nr_counters;
+    if (nbr_val)
+        *nbr_val = op.u.perfccontrol.nr_vals;
+
+    return rc;
 }
 
 long long xc_msr_read(int xc_handle, int cpu_mask, int msr)
diff -r 47af0e2ebb13 -r 7924b6bd728a tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Mon Aug 07 15:42:25 2006 +0100
+++ b/tools/libxc/xenctrl.h     Mon Aug 07 15:53:06 2006 +0100
@@ -466,10 +466,15 @@ unsigned long xc_make_page_below_4G(int 
                                     unsigned long mfn);
 
 typedef dom0_perfc_desc_t xc_perfc_desc_t;
-/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
+typedef dom0_perfc_val_t xc_perfc_val_t;
+/* IMPORTANT: The caller is responsible for mlock()'ing the @desc and @val
+   arrays. */
 int xc_perfc_control(int xc_handle,
                      uint32_t op,
-                     xc_perfc_desc_t *desc);
+                     xc_perfc_desc_t *desc,
+                     xc_perfc_val_t *val,
+                     int *nbr_desc,
+                     int *nbr_val);
 
 /* read/write msr */
 long long xc_msr_read(int xc_handle, int cpu_mask, int msr);
diff -r 47af0e2ebb13 -r 7924b6bd728a tools/misc/xenperf.c
--- a/tools/misc/xenperf.c      Mon Aug 07 15:42:25 2006 +0100
+++ b/tools/misc/xenperf.c      Mon Aug 07 15:53:06 2006 +0100
@@ -22,7 +22,10 @@ int main(int argc, char *argv[])
 {
     int              i, j, xc_handle;
     xc_perfc_desc_t *pcd;
-    unsigned int     num, sum, reset = 0, full = 0;
+       xc_perfc_val_t  *pcv;
+       xc_perfc_val_t  *val;
+       int num_desc, num_val;
+    unsigned int    sum, reset = 0, full = 0;
 
     if ( argc > 1 )
     {
@@ -62,7 +65,7 @@ int main(int argc, char *argv[])
     if ( reset )
     {
         if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_RESET,
-                              NULL) < 0 )
+                              NULL, NULL, NULL, NULL) != 0 )
         {
             fprintf(stderr, "Error reseting performance counters: %d (%s)\n",
                     errno, strerror(errno));
@@ -72,47 +75,54 @@ int main(int argc, char *argv[])
         return 0;
     }
 
+       if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
+                                                 NULL, NULL, &num_desc, 
&num_val) != 0 )
+        {
+            fprintf(stderr, "Error getting number of perf counters: %d (%s)\n",
+                    errno, strerror(errno));
+            return 1;
+        }
 
-    if ( (num = xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
-                                 NULL)) < 0 )
+    pcd = malloc(sizeof(*pcd) * num_desc);
+       pcv = malloc(sizeof(*pcv) * num_val);
+
+    if ( pcd == NULL
+                || mlock(pcd, sizeof(*pcd) * num_desc) != 0
+                || pcv == NULL
+                || mlock(pcd, sizeof(*pcv) * num_val) != 0)
     {
-        fprintf(stderr, "Error getting number of perf counters: %d (%s)\n",
+        fprintf(stderr, "Could not alloc or mlock buffers: %d (%s)\n",
+                errno, strerror(errno));
+        exit(-1);
+    }
+
+    if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
+                                                 pcd, pcv, NULL, NULL) != 0 )
+    {
+        fprintf(stderr, "Error getting perf counter: %d (%s)\n",
                 errno, strerror(errno));
         return 1;
     }
 
-    pcd = malloc(sizeof(*pcd) * num);
+    munlock(pcd, sizeof(*pcd) * num_desc);
+    munlock(pcv, sizeof(*pcv) * num_val);
 
-    if ( mlock(pcd, sizeof(*pcd) * num) != 0 )
-    {
-        fprintf(stderr, "Could not mlock descriptor buffer: %d (%s)\n",
-                errno, strerror(errno));
-        exit(-1);
-    }
-
-    if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY, pcd) <= 0 )
-    {
-        fprintf(stderr, "Error getting perf counter description: %d (%s)\n",
-                errno, strerror(errno));
-        return 1;
-    }
-
-    munlock(pcd, sizeof(*pcd) * num);
-
-    for ( i = 0; i < num; i++ )
+       val = pcv;
+    for ( i = 0; i < num_desc; i++ )
     {
         printf ("%-35s ", pcd[i].name);
         
         sum = 0;
         for ( j = 0; j < pcd[i].nr_vals; j++ )
-            sum += pcd[i].vals[j];
+            sum += val[j];
         printf ("T=%10u ", (unsigned int)sum);
 
         if ( full || (pcd[i].nr_vals <= 4) )
             for ( j = 0; j < pcd[i].nr_vals; j++ )
-                printf(" %10u", (unsigned int)pcd[i].vals[j]);
+                printf(" %10u", (unsigned int)val[j]);
 
         printf("\n");
+               val += pcd[i].nr_vals;
     }
 
     return 0;
diff -r 47af0e2ebb13 -r 7924b6bd728a xen/common/perfc.c
--- a/xen/common/perfc.c        Mon Aug 07 15:42:25 2006 +0100
+++ b/xen/common/perfc.c        Mon Aug 07 15:53:06 2006 +0100
@@ -136,10 +136,14 @@ void perfc_reset(unsigned char key)
 }
 
 static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
+static dom0_perfc_val_t *perfc_vals;
+static int               perfc_nbr_vals;
 static int               perfc_init = 0;
-static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc)
+static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc,
+                           XEN_GUEST_HANDLE(dom0_perfc_val_t) val)
 {
     unsigned int i, j;
+    unsigned int v = 0;
     atomic_t *counters = (atomic_t *)&perfcounters;
 
     if ( guest_handle_is_null(desc) )
@@ -169,13 +173,13 @@ static int perfc_copy_info(XEN_GUEST_HAN
                 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
                 break;
             }
-
-            if ( perfc_d[i].nr_vals > ARRAY_SIZE(perfc_d[i].vals) )
-                perfc_d[i].nr_vals = ARRAY_SIZE(perfc_d[i].vals);
-        }
-
+            perfc_nbr_vals += perfc_d[i].nr_vals;
+        }
+        perfc_vals = xmalloc_array(dom0_perfc_val_t, perfc_nbr_vals);
         perfc_init = 1;
     }
+    if (perfc_vals == NULL)
+        return -ENOMEM;
 
     /* We gather the counts together every time. */
     for ( i = 0; i < NR_PERFCTRS; i++ )
@@ -184,26 +188,30 @@ static int perfc_copy_info(XEN_GUEST_HAN
         {
         case TYPE_SINGLE:
         case TYPE_S_SINGLE:
-            perfc_d[i].vals[0] = atomic_read(&counters[0]);
+            perfc_vals[v++] = atomic_read(&counters[0]);
             counters += 1;
             break;
         case TYPE_CPU:
         case TYPE_S_CPU:
             for ( j = 0; j < perfc_d[i].nr_vals; j++ )
-                perfc_d[i].vals[j] = atomic_read(&counters[j]);
+                perfc_vals[v++] = atomic_read(&counters[j]);
             counters += NR_CPUS;
             break;
         case TYPE_ARRAY:
         case TYPE_S_ARRAY:
             for ( j = 0; j < perfc_d[i].nr_vals; j++ )
-                perfc_d[i].vals[j] = atomic_read(&counters[j]);
+                perfc_vals[v++] = atomic_read(&counters[j]);
             counters += perfc_info[i].nr_elements;
             break;
         }
     }
-
-    return (copy_to_guest(desc, (dom0_perfc_desc_t *)perfc_d, NR_PERFCTRS) ?
-            -EFAULT : 0);
+    BUG_ON(v != perfc_nbr_vals);
+
+    if (copy_to_guest(desc, (dom0_perfc_desc_t *)perfc_d, NR_PERFCTRS))
+        return -EFAULT;
+    if (copy_to_guest(val, perfc_vals, perfc_nbr_vals))
+        return -EFAULT;
+    return 0;
 }
 
 /* Dom0 control of perf counters */
@@ -213,20 +221,18 @@ int perfc_control(dom0_perfccontrol_t *p
     u32 op = pc->op;
     int rc;
 
-    pc->nr_counters = NR_PERFCTRS;
-
     spin_lock(&lock);
 
     switch ( op )
     {
     case DOM0_PERFCCONTROL_OP_RESET:
-        perfc_copy_info(pc->desc);
+        perfc_copy_info(pc->desc, pc->val);
         perfc_reset(0);
         rc = 0;
         break;
 
     case DOM0_PERFCCONTROL_OP_QUERY:
-        perfc_copy_info(pc->desc);
+        perfc_copy_info(pc->desc, pc->val);
         rc = 0;
         break;
 
@@ -236,6 +242,9 @@ int perfc_control(dom0_perfccontrol_t *p
     }
 
     spin_unlock(&lock);
+
+    pc->nr_counters = NR_PERFCTRS;
+    pc->nr_vals = perfc_nbr_vals;
 
     return rc;
 }
diff -r 47af0e2ebb13 -r 7924b6bd728a xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Mon Aug 07 15:42:25 2006 +0100
+++ b/xen/include/public/dom0_ops.h     Mon Aug 07 15:53:06 2006 +0100
@@ -361,17 +361,20 @@ struct dom0_perfc_desc {
 struct dom0_perfc_desc {
     char         name[80];             /* name of perf counter */
     uint32_t     nr_vals;              /* number of values for this counter */
-    uint32_t     vals[64];             /* array of values */
 };
 typedef struct dom0_perfc_desc dom0_perfc_desc_t;
 DEFINE_XEN_GUEST_HANDLE(dom0_perfc_desc_t);
+typedef uint32_t dom0_perfc_val_t;
+DEFINE_XEN_GUEST_HANDLE(dom0_perfc_val_t);
 
 struct dom0_perfccontrol {
     /* IN variables. */
     uint32_t       op;                /*  DOM0_PERFCCONTROL_OP_??? */
     /* OUT variables. */
-    uint32_t       nr_counters;       /*  number of counters */
+    uint32_t       nr_counters;       /*  number of counters description  */
+    uint32_t       nr_vals;                      /*  number of values  */
     XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc; /*  counter information (or 
NULL) */
+    XEN_GUEST_HANDLE(dom0_perfc_val_t) val;   /*  counter values (or NULL)  */
 };
 typedef struct dom0_perfccontrol dom0_perfccontrol_t;
 DEFINE_XEN_GUEST_HANDLE(dom0_perfccontrol_t);

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