# 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
|