direct-io.hg

changeset 3231:9035b6656818

bitkeeper revision 1.1159.187.48 (41adc6420WlNaaoUkvfgNxl44rpYYg)

Export Xen s/w perfctrs to DOM0 via new 'xenperf' utility.
author kaf24@scramble.cl.cam.ac.uk
date Wed Dec 01 13:25:22 2004 +0000 (2004-12-01)
parents 99caf078a6e4
children f2e12f9f7cc8 e6337ed51082
files .rootkeys BitKeeper/etc/ignore tools/libxc/xc.h tools/libxc/xc_misc.c tools/misc/Makefile tools/misc/xenperf.c xen/arch/x86/memory.c xen/common/dom0_ops.c xen/common/perfc.c xen/include/public/dom0_ops.h
line diff
     1.1 --- a/.rootkeys	Wed Dec 01 11:24:11 2004 +0000
     1.2 +++ b/.rootkeys	Wed Dec 01 13:25:22 2004 +0000
     1.3 @@ -380,6 +380,7 @@ 3f5ef5a2ir1kVAthS14Dc5QIRCEFWg tools/mis
     1.4  3f5ef5a2dTZP0nnsFoeq2jRf3mWDDg tools/misc/xen-clone.README
     1.5  405eedf6_nnNhFQ1I85lhCkLK6jFGA tools/misc/xencons
     1.6  40c9c4697z76HDfkCLdMhmaEwzFoNQ tools/misc/xend
     1.7 +41adc641dV-0cDLSyzMs5BT8nL7v3Q tools/misc/xenperf.c
     1.8  4107986eMWVdBoz4tXYoOscpN_BCYg tools/misc/xensv
     1.9  4056f5155QYZdsk-1fLdjsZPFTnlhg tools/misc/xensymoops
    1.10  40cf2937dqM1jWW87O5OoOYND8leuA tools/misc/xm
     2.1 --- a/BitKeeper/etc/ignore	Wed Dec 01 11:24:11 2004 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Wed Dec 01 13:25:22 2004 +0000
     2.3 @@ -58,7 +58,7 @@ tools/balloon/balloon
     2.4  tools/check/.*
     2.5  tools/libxc/xen/*
     2.6  tools/misc/miniterm/miniterm
     2.7 -tools/misc/xen_cpuperf
     2.8 +tools/misc/xenperf
     2.9  tools/vnet/gc
    2.10  tools/vnet/gc*/*
    2.11  tools/vnet/vnet-module/.tmp_versions/*
     3.1 --- a/tools/libxc/xc.h	Wed Dec 01 11:24:11 2004 +0000
     3.2 +++ b/tools/libxc/xc.h	Wed Dec 01 13:25:22 2004 +0000
     3.3 @@ -178,14 +178,19 @@ int xc_domain_setinitialmem(int xc_handl
     3.4                              unsigned int initial_memkb);
     3.5  
     3.6  int xc_domain_setmaxmem(int xc_handle,
     3.7 -                            u32 domid, 
     3.8 -                            unsigned int max_memkb);
     3.9 +                        u32 domid, 
    3.10 +                        unsigned int max_memkb);
    3.11  
    3.12  int xc_domain_setvmassist(int xc_handle,
    3.13                            u32 domid, 
    3.14                            unsigned int cmd,
    3.15                            unsigned int type);
    3.16  
    3.17 +typedef dom0_perfc_desc_t xc_perfc_desc_t;
    3.18 +/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
    3.19 +int xc_perfc_control(int xc_handle,
    3.20 +                     u32 op,
    3.21 +                     xc_perfc_desc_t *desc);
    3.22  
    3.23  void *xc_map_foreign_range(int xc_handle, u32 dom,
    3.24                              int size, int prot,
     4.1 --- a/tools/libxc/xc_misc.c	Wed Dec 01 11:24:11 2004 +0000
     4.2 +++ b/tools/libxc/xc_misc.c	Wed Dec 01 13:25:22 2004 +0000
     4.3 @@ -74,10 +74,26 @@ int xc_sched_id(int xc_handle,
     4.4      op.cmd = DOM0_SCHED_ID;
     4.5      op.interface_version = DOM0_INTERFACE_VERSION;
     4.6      
     4.7 -    if((ret = do_dom0_op(xc_handle, &op))) return ret;
     4.8 +    if ( (ret = do_dom0_op(xc_handle, &op)) != 0 )
     4.9 +        return ret;
    4.10      
    4.11      *sched_id = op.u.sched_id.sched_id;
    4.12      
    4.13      return 0;
    4.14  }
    4.15  
    4.16 +int xc_perfc_control(int xc_handle,
    4.17 +                     u32 op,
    4.18 +                     xc_perfc_desc_t *desc)
    4.19 +{
    4.20 +    int rc;
    4.21 +    dom0_op_t dop;
    4.22 +
    4.23 +    dop.cmd = DOM0_PERFCCONTROL;
    4.24 +    dop.u.perfccontrol.op   = op;
    4.25 +    dop.u.perfccontrol.desc = desc;
    4.26 +
    4.27 +    rc = do_dom0_op(xc_handle, &dop);
    4.28 +
    4.29 +    return (rc == 0) ? dop.u.perfccontrol.nr_counters : rc;
    4.30 +}
     5.1 --- a/tools/misc/Makefile	Wed Dec 01 11:24:11 2004 +0000
     5.2 +++ b/tools/misc/Makefile	Wed Dec 01 13:25:22 2004 +0000
     5.3 @@ -3,22 +3,18 @@ XEN_ROOT=../..
     5.4  include $(XEN_ROOT)/tools/Make.defs
     5.5  
     5.6  CC         = gcc
     5.7 -CFLAGS     = -Wall -O3 
     5.8 +CFLAGS     = -Wall -Werror -O3 
     5.9  
    5.10  INCLUDES += -I $(XEN_XC)
    5.11  INCLUDES += -I $(XEN_LIBXC)
    5.12 -INCLUDES += -I $(XEN_LIBXUTIL)
    5.13 -
    5.14 -CFLAGS += $(INCLUDES)
    5.15 +CFLAGS   += $(INCLUDES)
    5.16  
    5.17  HDRS     = $(wildcard *.h)
    5.18 -SRCS     = $(wildcard *.c)
    5.19 -OBJS     = $(patsubst %.c,%.o,$(SRCS))
    5.20  
    5.21 -TARGETS  = 
    5.22 +TARGETS  = xenperf
    5.23  
    5.24  INSTALL_BIN  = $(TARGETS) xencons
    5.25 -INSTALL_SBIN = netfix xm xend xensv
    5.26 +INSTALL_SBIN = netfix xm xend xensv xenperf
    5.27  
    5.28  all: $(TARGETS)
    5.29  	$(MAKE) -C miniterm
    5.30 @@ -32,7 +28,7 @@ install: all
    5.31  
    5.32  clean:
    5.33  	$(RM) *.o $(TARGETS) *~
    5.34 -	$(MAKE) -C miniterm clean	
    5.35 +	$(MAKE) -C miniterm clean
    5.36  
    5.37  %: %.c $(HDRS) Makefile
    5.38 -	$(CC) $(CFLAGS) -o $@ $<
    5.39 +	$(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/misc/xenperf.c	Wed Dec 01 13:25:22 2004 +0000
     6.3 @@ -0,0 +1,104 @@
     6.4 +/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
     6.5 + ****************************************************************************
     6.6 + * (C) 2004 - Rolf Neugebauer - Intel Research Cambridge
     6.7 + ****************************************************************************
     6.8 + *
     6.9 + *        File: xenperf.c
    6.10 + *      Author: Rolf Neugebauer (rolf.neugebauer@intel.com)
    6.11 + *        Date: Nov 2004
    6.12 + * 
    6.13 + * Description: 
    6.14 + */
    6.15 +
    6.16 +
    6.17 +#include <xc.h>
    6.18 +#include <stdio.h>
    6.19 +#include <stdlib.h>
    6.20 +#include <sys/mman.h>
    6.21 +#include <errno.h>
    6.22 +#include <string.h>
    6.23 +
    6.24 +int main(int argc, char *argv[])
    6.25 +{
    6.26 +    int              i, j, xc_handle;
    6.27 +    xc_perfc_desc_t *pcd;
    6.28 +    unsigned int     num, sum, reset = 0;
    6.29 +
    6.30 +    if ( argc > 1 )
    6.31 +    {
    6.32 +        char *p = argv[1];
    6.33 +        if ( (*p++ == '-')  && (*p == 'r') )
    6.34 +            reset = 1;
    6.35 +        else
    6.36 +        {
    6.37 +            printf("%s: [-r]\n", argv[0]);
    6.38 +            printf("no args: print xen performance counters\n");
    6.39 +            printf("    -r : reset xen performance counters\n");
    6.40 +            return 0;
    6.41 +        }
    6.42 +    }   
    6.43 +
    6.44 +    if ( (xc_handle = xc_interface_open()) == -1 )
    6.45 +    {
    6.46 +        fprintf(stderr, "Error opening xc interface: %d (%s)\n",
    6.47 +                errno, strerror(errno));
    6.48 +        return 1;
    6.49 +    }
    6.50 +    
    6.51 +    if ( reset )
    6.52 +    {
    6.53 +        if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_RESET,
    6.54 +                              NULL) < 0 )
    6.55 +        {
    6.56 +            fprintf(stderr, "Error reseting performance counters: %d (%s)\n",
    6.57 +                    errno, strerror(errno));
    6.58 +            return 1;
    6.59 +        }
    6.60 +
    6.61 +        return 0;
    6.62 +    }
    6.63 +
    6.64 +
    6.65 +    if ( (num = xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY,
    6.66 +                                 NULL)) < 0 )
    6.67 +    {
    6.68 +        fprintf(stderr, "Error getting number of perf counters: %d (%s)\n",
    6.69 +                errno, strerror(errno));
    6.70 +        return 1;
    6.71 +    }
    6.72 +
    6.73 +    pcd = malloc(sizeof(*pcd) * num);
    6.74 +
    6.75 +    if ( mlock(pcd, sizeof(*pcd) * num) != 0 )
    6.76 +    {
    6.77 +        fprintf(stderr, "Could not mlock descriptor buffer: %d (%s)\n",
    6.78 +                errno, strerror(errno));
    6.79 +        exit(-1);
    6.80 +    }
    6.81 +
    6.82 +    if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY, pcd) <= 0 )
    6.83 +    {
    6.84 +        fprintf(stderr, "Error getting perf counter description: %d (%s)\n",
    6.85 +                errno, strerror(errno));
    6.86 +        return 1;
    6.87 +    }
    6.88 +
    6.89 +    munlock(pcd, sizeof(*pcd) * num);
    6.90 +
    6.91 +    for ( i = 0; i < num; i++ )
    6.92 +    {
    6.93 +        printf ("%-35s ", pcd[i].name);
    6.94 +        
    6.95 +        sum = 0;
    6.96 +        for ( j = 0; j < pcd[i].nr_vals; j++ )
    6.97 +            sum += pcd[i].vals[j];
    6.98 +        printf ("T=%10u ", (unsigned int)sum);
    6.99 +
   6.100 +        for ( j = 0; j < pcd[i].nr_vals; j++ )
   6.101 +            printf(" %10u", (unsigned int)pcd[i].vals[j]);
   6.102 +
   6.103 +        printf("\n");
   6.104 +    }
   6.105 +
   6.106 +    return 0;
   6.107 +}
     7.1 --- a/xen/arch/x86/memory.c	Wed Dec 01 11:24:11 2004 +0000
     7.2 +++ b/xen/arch/x86/memory.c	Wed Dec 01 13:25:22 2004 +0000
     7.3 @@ -1299,9 +1299,6 @@ int do_mmu_update(
     7.4      u32 type_info;
     7.5      domid_t domid;
     7.6  
     7.7 -    perfc_incrc(calls_to_mmu_update); 
     7.8 -    perfc_addc(num_page_updates, count);
     7.9 -
    7.10      cleanup_writable_pagetable(d, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
    7.11  
    7.12      /*
    7.13 @@ -1331,6 +1328,9 @@ int do_mmu_update(
    7.14          }
    7.15      }
    7.16  
    7.17 +    perfc_incrc(calls_to_mmu_update); 
    7.18 +    perfc_addc(num_page_updates, count);
    7.19 +
    7.20      if ( unlikely(!array_access_ok(VERIFY_READ, ureqs, count, sizeof(req))) )
    7.21      {
    7.22          rc = -EFAULT;
     8.1 --- a/xen/common/dom0_ops.c	Wed Dec 01 11:24:11 2004 +0000
     8.2 +++ b/xen/common/dom0_ops.c	Wed Dec 01 13:25:22 2004 +0000
     8.3 @@ -651,6 +651,16 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     8.4      }
     8.5      break;
     8.6  
     8.7 +#ifdef PERF_COUNTERS
     8.8 +    case DOM0_PERFCCONTROL:
     8.9 +    {
    8.10 +        extern int perfc_control(dom0_perfccontrol_t *);
    8.11 +        ret = perfc_control(&op->u.perfccontrol);
    8.12 +        copy_to_user(u_dom0_op, op, sizeof(*op));
    8.13 +    }
    8.14 +    break;
    8.15 +#endif
    8.16 +
    8.17      default:
    8.18          ret = arch_do_dom0_op(op,u_dom0_op);
    8.19  
     9.1 --- a/xen/common/perfc.c	Wed Dec 01 11:24:11 2004 +0000
     9.2 +++ b/xen/common/perfc.c	Wed Dec 01 13:25:22 2004 +0000
     9.3 @@ -4,6 +4,8 @@
     9.4  #include <xen/time.h>
     9.5  #include <xen/perfc.h>
     9.6  #include <xen/keyhandler.h> 
     9.7 +#include <public/dom0_ops.h>
     9.8 +#include <asm/uaccess.h>
     9.9  
    9.10  #undef  PERFCOUNTER
    9.11  #undef  PERFCOUNTER_CPU
    9.12 @@ -79,8 +81,9 @@ void perfc_reset(unsigned char key)
    9.13      s_time_t now = NOW();
    9.14      atomic_t *counters = (atomic_t *)&perfcounters;
    9.15  
    9.16 -    printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
    9.17 -           (u32)(now>>32), (u32)now);
    9.18 +    if ( key != '\0' )
    9.19 +        printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
    9.20 +               (u32)(now>>32), (u32)now);
    9.21  
    9.22      /* leave STATUS counters alone -- don't reset */
    9.23  
    9.24 @@ -109,3 +112,107 @@ void perfc_reset(unsigned char key)
    9.25      }
    9.26  }
    9.27  
    9.28 +static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
    9.29 +static int               perfc_init = 0;
    9.30 +static int perfc_copy_info(dom0_perfc_desc_t *desc)
    9.31 +{
    9.32 +    unsigned int i, j;
    9.33 +    atomic_t *counters = (atomic_t *)&perfcounters;
    9.34 +
    9.35 +    if ( desc == NULL )
    9.36 +        return 0;
    9.37 +
    9.38 +    /* We only copy the name and array-size information once. */
    9.39 +    if ( !perfc_init ) 
    9.40 +    {
    9.41 +        for ( i = 0; i < NR_PERFCTRS; i++ )
    9.42 +        {
    9.43 +            strncpy(perfc_d[i].name, perfc_info[i].name,
    9.44 +                    sizeof(perfc_d[i].name));
    9.45 +            perfc_d[i].name[sizeof(perfc_d[i].name)-1] = '\0';
    9.46 +
    9.47 +            switch ( perfc_info[i].type )
    9.48 +            {
    9.49 +            case TYPE_SINGLE:
    9.50 +            case TYPE_S_SINGLE:
    9.51 +                perfc_d[i].nr_vals = 1;
    9.52 +                break;
    9.53 +            case TYPE_CPU:
    9.54 +            case TYPE_S_CPU:
    9.55 +                perfc_d[i].nr_vals = smp_num_cpus;
    9.56 +                break;
    9.57 +            case TYPE_ARRAY:
    9.58 +            case TYPE_S_ARRAY:
    9.59 +                perfc_d[i].nr_vals = perfc_info[i].nr_elements;
    9.60 +                break;
    9.61 +            }
    9.62 +
    9.63 +            if ( perfc_d[i].nr_vals > ARRAY_SIZE(perfc_d[i].vals) )
    9.64 +                perfc_d[i].nr_vals = ARRAY_SIZE(perfc_d[i].vals);
    9.65 +        }
    9.66 +
    9.67 +        perfc_init = 1;
    9.68 +    }
    9.69 +
    9.70 +    /* We gather the counts together every time. */
    9.71 +    for ( i = 0; i < NR_PERFCTRS; i++ )
    9.72 +    {
    9.73 +        switch ( perfc_info[i].type )
    9.74 +        {
    9.75 +        case TYPE_SINGLE:
    9.76 +        case TYPE_S_SINGLE:
    9.77 +            perfc_d[i].vals[0] = atomic_read(&counters[0]);
    9.78 +            counters += 1;
    9.79 +            break;
    9.80 +        case TYPE_CPU:
    9.81 +        case TYPE_S_CPU:
    9.82 +            for ( j = 0; j < perfc_d[i].nr_vals; j++ )
    9.83 +                perfc_d[i].vals[j] = atomic_read(&counters[j]);
    9.84 +            counters += NR_CPUS;
    9.85 +            break;
    9.86 +        case TYPE_ARRAY:
    9.87 +        case TYPE_S_ARRAY:
    9.88 +            for ( j = 0; j < perfc_d[i].nr_vals; j++ )
    9.89 +                perfc_d[i].vals[j] = atomic_read(&counters[j]);
    9.90 +            counters += perfc_info[i].nr_elements;
    9.91 +            break;
    9.92 +        }
    9.93 +    }
    9.94 +
    9.95 +    return (copy_to_user(desc, perfc_d, NR_PERFCTRS * sizeof(*desc)) ?
    9.96 +            -EFAULT : 0);
    9.97 +}
    9.98 +
    9.99 +/* Dom0 control of perf counters */
   9.100 +int perfc_control(dom0_perfccontrol_t *pc)
   9.101 +{
   9.102 +    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
   9.103 +    u32 op = pc->op;
   9.104 +    int rc;
   9.105 +
   9.106 +    pc->nr_counters = NR_PERFCTRS;
   9.107 +
   9.108 +    spin_lock(&lock);
   9.109 +
   9.110 +    switch ( op )
   9.111 +    {
   9.112 +    case DOM0_PERFCCONTROL_OP_RESET:
   9.113 +        perfc_copy_info(pc->desc);
   9.114 +        perfc_reset(0);
   9.115 +        rc = 0;
   9.116 +        break;
   9.117 +
   9.118 +    case DOM0_PERFCCONTROL_OP_QUERY:
   9.119 +        perfc_copy_info(pc->desc);
   9.120 +        rc = 0;
   9.121 +        break;
   9.122 +
   9.123 +    default:
   9.124 +        rc = -EINVAL;
   9.125 +        break;
   9.126 +    }
   9.127 +
   9.128 +    spin_unlock(&lock);
   9.129 +
   9.130 +    return rc;
   9.131 +}
    10.1 --- a/xen/include/public/dom0_ops.h	Wed Dec 01 11:24:11 2004 +0000
    10.2 +++ b/xen/include/public/dom0_ops.h	Wed Dec 01 13:25:22 2004 +0000
    10.3 @@ -386,6 +386,25 @@ typedef struct {
    10.4      u32      __pad1;
    10.5  } PACKED dom0_read_memtype_t; /* 32 bytes */
    10.6  
    10.7 +/* Interface for controlling Xen software performance counters. */
    10.8 +#define DOM0_PERFCCONTROL        34
    10.9 +/* Sub-operations: */
   10.10 +#define DOM0_PERFCCONTROL_OP_RESET 1   /* Reset all counters to zero. */
   10.11 +#define DOM0_PERFCCONTROL_OP_QUERY 2   /* Get perfctr information. */
   10.12 +typedef struct {
   10.13 +    u8      name[80];               /*  0: name of perf counter */
   10.14 +    u32     nr_vals;                /* 80: number of values for this counter */
   10.15 +    u32     vals[64];               /* 84: array of values */
   10.16 +} PACKED dom0_perfc_desc_t; /* 340 bytes */
   10.17 +typedef struct {
   10.18 +    /* IN variables. */
   10.19 +    u32            op;                /*  0: DOM0_PERFCCONTROL_OP_??? */
   10.20 +    /* OUT variables. */
   10.21 +    u32            nr_counters;       /*  4: number of counters */
   10.22 +    dom0_perfc_desc_t *desc;          /*  8: counter information (or NULL) */
   10.23 +    MEMORY_PADDING;
   10.24 +} PACKED dom0_perfccontrol_t; /* 16 bytes */
   10.25 +
   10.26  typedef struct {
   10.27      u32 cmd;                          /* 0 */
   10.28      u32 interface_version;            /* 4 */ /* DOM0_INTERFACE_VERSION */
   10.29 @@ -419,6 +438,7 @@ typedef struct {
   10.30          dom0_add_memtype_t       add_memtype;
   10.31          dom0_del_memtype_t       del_memtype;
   10.32          dom0_read_memtype_t      read_memtype;
   10.33 +        dom0_perfccontrol_t      perfccontrol;
   10.34      } PACKED u;
   10.35  } PACKED dom0_op_t; /* 80 bytes */
   10.36