ia64/xen-unstable

changeset 10981:7924b6bd728a

Change DOM0_PERFCCONTROL: remove array limit.

Descriptors and values are passed by two distinct buffers.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author kaf24@firebug.cl.cam.ac.uk
date Mon Aug 07 15:53:06 2006 +0100 (2006-08-07)
parents 47af0e2ebb13
children 6289234304f1
files tools/libxc/xc_misc.c tools/libxc/xenctrl.h tools/misc/xenperf.c xen/common/perfc.c xen/include/public/dom0_ops.h
line diff
     1.1 --- a/tools/libxc/xc_misc.c	Mon Aug 07 15:42:25 2006 +0100
     1.2 +++ b/tools/libxc/xc_misc.c	Mon Aug 07 15:53:06 2006 +0100
     1.3 @@ -68,7 +68,10 @@ int xc_sched_id(int xc_handle,
     1.4  
     1.5  int xc_perfc_control(int xc_handle,
     1.6                       uint32_t opcode,
     1.7 -                     xc_perfc_desc_t *desc)
     1.8 +                     xc_perfc_desc_t *desc,
     1.9 +                     xc_perfc_val_t *val,
    1.10 +                     int *nbr_desc,
    1.11 +                     int *nbr_val)
    1.12  {
    1.13      int rc;
    1.14      DECLARE_DOM0_OP;
    1.15 @@ -76,10 +79,16 @@ int xc_perfc_control(int xc_handle,
    1.16      op.cmd = DOM0_PERFCCONTROL;
    1.17      op.u.perfccontrol.op   = opcode;
    1.18      set_xen_guest_handle(op.u.perfccontrol.desc, desc);
    1.19 +    set_xen_guest_handle(op.u.perfccontrol.val, val);
    1.20  
    1.21      rc = do_dom0_op(xc_handle, &op);
    1.22  
    1.23 -    return (rc == 0) ? op.u.perfccontrol.nr_counters : rc;
    1.24 +    if (nbr_desc)
    1.25 +        *nbr_desc = op.u.perfccontrol.nr_counters;
    1.26 +    if (nbr_val)
    1.27 +        *nbr_val = op.u.perfccontrol.nr_vals;
    1.28 +
    1.29 +    return rc;
    1.30  }
    1.31  
    1.32  long long xc_msr_read(int xc_handle, int cpu_mask, int msr)
     2.1 --- a/tools/libxc/xenctrl.h	Mon Aug 07 15:42:25 2006 +0100
     2.2 +++ b/tools/libxc/xenctrl.h	Mon Aug 07 15:53:06 2006 +0100
     2.3 @@ -466,10 +466,15 @@ unsigned long xc_make_page_below_4G(int 
     2.4                                      unsigned long mfn);
     2.5  
     2.6  typedef dom0_perfc_desc_t xc_perfc_desc_t;
     2.7 -/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
     2.8 +typedef dom0_perfc_val_t xc_perfc_val_t;
     2.9 +/* IMPORTANT: The caller is responsible for mlock()'ing the @desc and @val
    2.10 +   arrays. */
    2.11  int xc_perfc_control(int xc_handle,
    2.12                       uint32_t op,
    2.13 -                     xc_perfc_desc_t *desc);
    2.14 +                     xc_perfc_desc_t *desc,
    2.15 +                     xc_perfc_val_t *val,
    2.16 +                     int *nbr_desc,
    2.17 +                     int *nbr_val);
    2.18  
    2.19  /* read/write msr */
    2.20  long long xc_msr_read(int xc_handle, int cpu_mask, int msr);
     3.1 --- a/tools/misc/xenperf.c	Mon Aug 07 15:42:25 2006 +0100
     3.2 +++ b/tools/misc/xenperf.c	Mon Aug 07 15:53:06 2006 +0100
     3.3 @@ -22,7 +22,10 @@ int main(int argc, char *argv[])
     3.4  {
     3.5      int              i, j, xc_handle;
     3.6      xc_perfc_desc_t *pcd;
     3.7 -    unsigned int     num, sum, reset = 0, full = 0;
     3.8 +	xc_perfc_val_t  *pcv;
     3.9 +	xc_perfc_val_t  *val;
    3.10 +	int num_desc, num_val;
    3.11 +    unsigned int    sum, reset = 0, full = 0;
    3.12  
    3.13      if ( argc > 1 )
    3.14      {
    3.15 @@ -62,7 +65,7 @@ int main(int argc, char *argv[])
    3.16      if ( reset )
    3.17      {
    3.18          if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_RESET,
    3.19 -                              NULL) < 0 )
    3.20 +                              NULL, NULL, NULL, NULL) != 0 )
    3.21          {
    3.22              fprintf(stderr, "Error reseting performance counters: %d (%s)\n",
    3.23                      errno, strerror(errno));
    3.24 @@ -72,47 +75,54 @@ int main(int argc, char *argv[])
    3.25          return 0;
    3.26      }
    3.27  
    3.28 +	if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
    3.29 +						  NULL, NULL, &num_desc, &num_val) != 0 )
    3.30 +        {
    3.31 +            fprintf(stderr, "Error getting number of perf counters: %d (%s)\n",
    3.32 +                    errno, strerror(errno));
    3.33 +            return 1;
    3.34 +        }
    3.35  
    3.36 -    if ( (num = xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
    3.37 -                                 NULL)) < 0 )
    3.38 +    pcd = malloc(sizeof(*pcd) * num_desc);
    3.39 +	pcv = malloc(sizeof(*pcv) * num_val);
    3.40 +
    3.41 +    if ( pcd == NULL
    3.42 +		 || mlock(pcd, sizeof(*pcd) * num_desc) != 0
    3.43 +		 || pcv == NULL
    3.44 +		 || mlock(pcd, sizeof(*pcv) * num_val) != 0)
    3.45      {
    3.46 -        fprintf(stderr, "Error getting number of perf counters: %d (%s)\n",
    3.47 +        fprintf(stderr, "Could not alloc or mlock buffers: %d (%s)\n",
    3.48 +                errno, strerror(errno));
    3.49 +        exit(-1);
    3.50 +    }
    3.51 +
    3.52 +    if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
    3.53 +						  pcd, pcv, NULL, NULL) != 0 )
    3.54 +    {
    3.55 +        fprintf(stderr, "Error getting perf counter: %d (%s)\n",
    3.56                  errno, strerror(errno));
    3.57          return 1;
    3.58      }
    3.59  
    3.60 -    pcd = malloc(sizeof(*pcd) * num);
    3.61 -
    3.62 -    if ( mlock(pcd, sizeof(*pcd) * num) != 0 )
    3.63 -    {
    3.64 -        fprintf(stderr, "Could not mlock descriptor buffer: %d (%s)\n",
    3.65 -                errno, strerror(errno));
    3.66 -        exit(-1);
    3.67 -    }
    3.68 +    munlock(pcd, sizeof(*pcd) * num_desc);
    3.69 +    munlock(pcv, sizeof(*pcv) * num_val);
    3.70  
    3.71 -    if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY, pcd) <= 0 )
    3.72 -    {
    3.73 -        fprintf(stderr, "Error getting perf counter description: %d (%s)\n",
    3.74 -                errno, strerror(errno));
    3.75 -        return 1;
    3.76 -    }
    3.77 -
    3.78 -    munlock(pcd, sizeof(*pcd) * num);
    3.79 -
    3.80 -    for ( i = 0; i < num; i++ )
    3.81 +	val = pcv;
    3.82 +    for ( i = 0; i < num_desc; i++ )
    3.83      {
    3.84          printf ("%-35s ", pcd[i].name);
    3.85          
    3.86          sum = 0;
    3.87          for ( j = 0; j < pcd[i].nr_vals; j++ )
    3.88 -            sum += pcd[i].vals[j];
    3.89 +            sum += val[j];
    3.90          printf ("T=%10u ", (unsigned int)sum);
    3.91  
    3.92          if ( full || (pcd[i].nr_vals <= 4) )
    3.93              for ( j = 0; j < pcd[i].nr_vals; j++ )
    3.94 -                printf(" %10u", (unsigned int)pcd[i].vals[j]);
    3.95 +                printf(" %10u", (unsigned int)val[j]);
    3.96  
    3.97          printf("\n");
    3.98 +		val += pcd[i].nr_vals;
    3.99      }
   3.100  
   3.101      return 0;
     4.1 --- a/xen/common/perfc.c	Mon Aug 07 15:42:25 2006 +0100
     4.2 +++ b/xen/common/perfc.c	Mon Aug 07 15:53:06 2006 +0100
     4.3 @@ -136,10 +136,14 @@ void perfc_reset(unsigned char key)
     4.4  }
     4.5  
     4.6  static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
     4.7 +static dom0_perfc_val_t *perfc_vals;
     4.8 +static int               perfc_nbr_vals;
     4.9  static int               perfc_init = 0;
    4.10 -static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc)
    4.11 +static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc,
    4.12 +                           XEN_GUEST_HANDLE(dom0_perfc_val_t) val)
    4.13  {
    4.14      unsigned int i, j;
    4.15 +    unsigned int v = 0;
    4.16      atomic_t *counters = (atomic_t *)&perfcounters;
    4.17  
    4.18      if ( guest_handle_is_null(desc) )
    4.19 @@ -169,13 +173,13 @@ static int perfc_copy_info(XEN_GUEST_HAN
    4.20                  perfc_d[i].nr_vals = perfc_info[i].nr_elements;
    4.21                  break;
    4.22              }
    4.23 -
    4.24 -            if ( perfc_d[i].nr_vals > ARRAY_SIZE(perfc_d[i].vals) )
    4.25 -                perfc_d[i].nr_vals = ARRAY_SIZE(perfc_d[i].vals);
    4.26 +            perfc_nbr_vals += perfc_d[i].nr_vals;
    4.27          }
    4.28 -
    4.29 +        perfc_vals = xmalloc_array(dom0_perfc_val_t, perfc_nbr_vals);
    4.30          perfc_init = 1;
    4.31      }
    4.32 +    if (perfc_vals == NULL)
    4.33 +        return -ENOMEM;
    4.34  
    4.35      /* We gather the counts together every time. */
    4.36      for ( i = 0; i < NR_PERFCTRS; i++ )
    4.37 @@ -184,26 +188,30 @@ static int perfc_copy_info(XEN_GUEST_HAN
    4.38          {
    4.39          case TYPE_SINGLE:
    4.40          case TYPE_S_SINGLE:
    4.41 -            perfc_d[i].vals[0] = atomic_read(&counters[0]);
    4.42 +            perfc_vals[v++] = atomic_read(&counters[0]);
    4.43              counters += 1;
    4.44              break;
    4.45          case TYPE_CPU:
    4.46          case TYPE_S_CPU:
    4.47              for ( j = 0; j < perfc_d[i].nr_vals; j++ )
    4.48 -                perfc_d[i].vals[j] = atomic_read(&counters[j]);
    4.49 +                perfc_vals[v++] = atomic_read(&counters[j]);
    4.50              counters += NR_CPUS;
    4.51              break;
    4.52          case TYPE_ARRAY:
    4.53          case TYPE_S_ARRAY:
    4.54              for ( j = 0; j < perfc_d[i].nr_vals; j++ )
    4.55 -                perfc_d[i].vals[j] = atomic_read(&counters[j]);
    4.56 +                perfc_vals[v++] = atomic_read(&counters[j]);
    4.57              counters += perfc_info[i].nr_elements;
    4.58              break;
    4.59          }
    4.60      }
    4.61 +    BUG_ON(v != perfc_nbr_vals);
    4.62  
    4.63 -    return (copy_to_guest(desc, (dom0_perfc_desc_t *)perfc_d, NR_PERFCTRS) ?
    4.64 -            -EFAULT : 0);
    4.65 +    if (copy_to_guest(desc, (dom0_perfc_desc_t *)perfc_d, NR_PERFCTRS))
    4.66 +        return -EFAULT;
    4.67 +    if (copy_to_guest(val, perfc_vals, perfc_nbr_vals))
    4.68 +        return -EFAULT;
    4.69 +    return 0;
    4.70  }
    4.71  
    4.72  /* Dom0 control of perf counters */
    4.73 @@ -213,20 +221,18 @@ int perfc_control(dom0_perfccontrol_t *p
    4.74      u32 op = pc->op;
    4.75      int rc;
    4.76  
    4.77 -    pc->nr_counters = NR_PERFCTRS;
    4.78 -
    4.79      spin_lock(&lock);
    4.80  
    4.81      switch ( op )
    4.82      {
    4.83      case DOM0_PERFCCONTROL_OP_RESET:
    4.84 -        perfc_copy_info(pc->desc);
    4.85 +        perfc_copy_info(pc->desc, pc->val);
    4.86          perfc_reset(0);
    4.87          rc = 0;
    4.88          break;
    4.89  
    4.90      case DOM0_PERFCCONTROL_OP_QUERY:
    4.91 -        perfc_copy_info(pc->desc);
    4.92 +        perfc_copy_info(pc->desc, pc->val);
    4.93          rc = 0;
    4.94          break;
    4.95  
    4.96 @@ -237,6 +243,9 @@ int perfc_control(dom0_perfccontrol_t *p
    4.97  
    4.98      spin_unlock(&lock);
    4.99  
   4.100 +    pc->nr_counters = NR_PERFCTRS;
   4.101 +    pc->nr_vals = perfc_nbr_vals;
   4.102 +
   4.103      return rc;
   4.104  }
   4.105  
     5.1 --- a/xen/include/public/dom0_ops.h	Mon Aug 07 15:42:25 2006 +0100
     5.2 +++ b/xen/include/public/dom0_ops.h	Mon Aug 07 15:53:06 2006 +0100
     5.3 @@ -361,17 +361,20 @@ DEFINE_XEN_GUEST_HANDLE(dom0_read_memtyp
     5.4  struct dom0_perfc_desc {
     5.5      char         name[80];             /* name of perf counter */
     5.6      uint32_t     nr_vals;              /* number of values for this counter */
     5.7 -    uint32_t     vals[64];             /* array of values */
     5.8  };
     5.9  typedef struct dom0_perfc_desc dom0_perfc_desc_t;
    5.10  DEFINE_XEN_GUEST_HANDLE(dom0_perfc_desc_t);
    5.11 +typedef uint32_t dom0_perfc_val_t;
    5.12 +DEFINE_XEN_GUEST_HANDLE(dom0_perfc_val_t);
    5.13  
    5.14  struct dom0_perfccontrol {
    5.15      /* IN variables. */
    5.16      uint32_t       op;                /*  DOM0_PERFCCONTROL_OP_??? */
    5.17      /* OUT variables. */
    5.18 -    uint32_t       nr_counters;       /*  number of counters */
    5.19 +    uint32_t       nr_counters;       /*  number of counters description  */
    5.20 +    uint32_t       nr_vals;			  /*  number of values  */
    5.21      XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc; /*  counter information (or NULL) */
    5.22 +    XEN_GUEST_HANDLE(dom0_perfc_val_t) val;   /*  counter values (or NULL)  */
    5.23  };
    5.24  typedef struct dom0_perfccontrol dom0_perfccontrol_t;
    5.25  DEFINE_XEN_GUEST_HANDLE(dom0_perfccontrol_t);