direct-io.hg

changeset 11460:1ece34466781

Add new operation XENOPROF_get_buffer in xenoprof hypercall. Also
remove buffer related arguments from XENOPROF_init operation. This
is the first step to allow dynamic mapping/unmapping of xenoprof
buffers to
enable profiling a domain in passive mode and then switch to active
mode (or vice-versa). Currently a domain can only be profiled in a
single mode. Also passive domains cannot have oprofile builtin the
kernel or passive profiling will fail.

Signed-off-by: Jose Renato Santos <jsantos@hpl.hp.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Sep 13 14:05:33 2006 +0100 (2006-09-13)
parents 98fcd017c5f3
children 21dc71840bc0
files linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c xen/arch/x86/oprofile/xenoprof.c xen/include/public/xenoprof.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c	Wed Sep 13 14:01:23 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c	Wed Sep 13 14:05:33 2006 +0100
     1.3 @@ -32,6 +32,8 @@
     1.4  #include <../../../drivers/oprofile/cpu_buffer.h>
     1.5  #include <../../../drivers/oprofile/event_buffer.h>
     1.6  
     1.7 +#define MAX_XENOPROF_SAMPLES 16
     1.8 +
     1.9  static int xenoprof_start(void);
    1.10  static void xenoprof_stop(void);
    1.11  
    1.12 @@ -43,7 +45,7 @@ static int active_defined;
    1.13  /* sample buffers shared with Xen */
    1.14  xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
    1.15  /* Shared buffer area */
    1.16 -char * shared_buffer;
    1.17 +char * shared_buffer = NULL;
    1.18  /* Number of buffers in shared area (one per VCPU) */
    1.19  int nbuf;
    1.20  /* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
    1.21 @@ -233,13 +235,57 @@ static int bind_virq(void)
    1.22  }
    1.23  
    1.24  
    1.25 +static int map_xenoprof_buffer(int max_samples)
    1.26 +{
    1.27 +	struct xenoprof_get_buffer get_buffer;
    1.28 +	struct xenoprof_buf *buf;
    1.29 +	int npages, ret, i;
    1.30 +	struct vm_struct *area;
    1.31 +
    1.32 +	if ( shared_buffer )
    1.33 +		return 0;
    1.34 +
    1.35 +	get_buffer.max_samples = max_samples;
    1.36 +
    1.37 +	if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) )
    1.38 +		return ret;
    1.39 +
    1.40 +	nbuf = get_buffer.nbuf;
    1.41 +	npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1;
    1.42 +
    1.43 +	area = alloc_vm_area(npages * PAGE_SIZE);
    1.44 +	if (area == NULL)
    1.45 +		return -ENOMEM;
    1.46 +
    1.47 +	if ( (ret = direct_kernel_remap_pfn_range(
    1.48 +		      (unsigned long)area->addr,
    1.49 +		      get_buffer.buf_maddr >> PAGE_SHIFT,
    1.50 +		      npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE), DOMID_SELF)) ) {
    1.51 +		vunmap(area->addr);
    1.52 +		return ret;
    1.53 +	}
    1.54 +
    1.55 +	shared_buffer = area->addr;
    1.56 +	for (i=0; i< nbuf; i++) {
    1.57 +		buf = (struct xenoprof_buf*) 
    1.58 +			&shared_buffer[i * get_buffer.bufsize];
    1.59 +		BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
    1.60 +		xenoprof_buf[buf->vcpu_id] = buf;
    1.61 +	}
    1.62 +
    1.63 +	return 0;
    1.64 +}
    1.65 +
    1.66 +
    1.67  static int xenoprof_setup(void)
    1.68  {
    1.69  	int ret;
    1.70  	int i;
    1.71  
    1.72 -	ret = bind_virq();
    1.73 -	if (ret)
    1.74 +	if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
    1.75 +		return ret;
    1.76 +
    1.77 +	if ( (ret = bind_virq()) )
    1.78  		return ret;
    1.79  
    1.80  	if (is_primary) {
    1.81 @@ -482,51 +528,19 @@ static int using_xenoprof;
    1.82  int __init oprofile_arch_init(struct oprofile_operations * ops)
    1.83  {
    1.84  	struct xenoprof_init init;
    1.85 -	struct xenoprof_buf *buf;
    1.86 -	int npages, ret, i;
    1.87 -	struct vm_struct *area;
    1.88 +	int ret, i;
    1.89  
    1.90 -	init.max_samples = 16;
    1.91  	ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
    1.92  
    1.93  	if (!ret) {
    1.94 -		pgprot_t prot = __pgprot(_KERNPG_TABLE);
    1.95 -
    1.96  		num_events = init.num_events;
    1.97  		is_primary = init.is_primary;
    1.98 -		nbuf = init.nbuf;
    1.99  
   1.100  		/* just in case - make sure we do not overflow event list 
   1.101 -                   (i.e. counter_config list) */
   1.102 +		   (i.e. counter_config list) */
   1.103  		if (num_events > OP_MAX_COUNTER)
   1.104  			num_events = OP_MAX_COUNTER;
   1.105  
   1.106 -		npages = (init.bufsize * nbuf - 1) / PAGE_SIZE + 1;
   1.107 -
   1.108 -		area = alloc_vm_area(npages * PAGE_SIZE);
   1.109 -		if (area == NULL) {
   1.110 -			ret = -ENOMEM;
   1.111 -			goto out;
   1.112 -		}
   1.113 -
   1.114 -		ret = direct_kernel_remap_pfn_range(
   1.115 -			(unsigned long)area->addr,
   1.116 -			init.buf_maddr >> PAGE_SHIFT,
   1.117 -			npages * PAGE_SIZE, prot, DOMID_SELF);
   1.118 -		if (ret) {
   1.119 -			vunmap(area->addr);
   1.120 -			goto out;
   1.121 -		}
   1.122 -
   1.123 -		shared_buffer = area->addr;
   1.124 -
   1.125 -		for (i=0; i< nbuf; i++) {
   1.126 -			buf = (struct xenoprof_buf*) 
   1.127 -				&shared_buffer[i * init.bufsize];
   1.128 -			BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
   1.129 -			xenoprof_buf[buf->vcpu_id] = buf;
   1.130 -		}
   1.131 -
   1.132  		/*  cpu_type is detected by Xen */
   1.133  		cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
   1.134  		strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
   1.135 @@ -541,7 +555,6 @@ int __init oprofile_arch_init(struct opr
   1.136  
   1.137  		active_defined = 0;
   1.138  	}
   1.139 - out:
   1.140  	printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, "
   1.141  	       "is_primary %d\n", ret, num_events, is_primary);
   1.142  	return ret;
     2.1 --- a/xen/arch/x86/oprofile/xenoprof.c	Wed Sep 13 14:01:23 2006 +0100
     2.2 +++ b/xen/arch/x86/oprofile/xenoprof.c	Wed Sep 13 14:05:33 2006 +0100
     2.3 @@ -437,54 +437,59 @@ void xenoprof_log_event(
     2.4  int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
     2.5  {
     2.6      struct xenoprof_init xenoprof_init;
     2.7 -    int is_primary, num_events;
     2.8 -    struct domain *d = current->domain;
     2.9      int ret;
    2.10  
    2.11      if ( copy_from_guest(&xenoprof_init, arg, 1) )
    2.12          return -EFAULT;
    2.13  
    2.14 -    ret = nmi_init(&num_events, 
    2.15 -                   &is_primary, 
    2.16 -                   xenoprof_init.cpu_type);
    2.17 -    if ( ret < 0 )
    2.18 -        goto err;
    2.19 +    if ( (ret = nmi_init(&xenoprof_init.num_events, 
    2.20 +                         &xenoprof_init.is_primary, 
    2.21 +                         xenoprof_init.cpu_type)) )
    2.22 +        return ret;
    2.23  
    2.24 -    if ( is_primary )
    2.25 +    if ( copy_to_guest(arg, &xenoprof_init, 1) )
    2.26 +        return -EFAULT;
    2.27 +
    2.28 +    if ( xenoprof_init.is_primary )
    2.29          primary_profiler = current->domain;
    2.30  
    2.31 +    return 0;
    2.32 +}
    2.33 +
    2.34 +int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
    2.35 +{
    2.36 +    struct xenoprof_get_buffer xenoprof_get_buffer;
    2.37 +    struct domain *d = current->domain;
    2.38 +    int ret;
    2.39 +
    2.40 +    if ( copy_from_guest(&xenoprof_get_buffer, arg, 1) )
    2.41 +        return -EFAULT;
    2.42 +
    2.43      /*
    2.44 -     * We allocate xenoprof struct and buffers only at first time xenoprof_init
    2.45 +     * We allocate xenoprof struct and buffers only at first time xenoprof_get_buffer
    2.46       * is called. Memory is then kept until domain is destroyed.
    2.47       */
    2.48      if ( (d->xenoprof == NULL) &&
    2.49 -         ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples, 0)) < 0) )
    2.50 -        goto err;
    2.51 +         ((ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0)) < 0) )
    2.52 +        return ret;
    2.53  
    2.54      xenoprof_reset_buf(d);
    2.55  
    2.56      d->xenoprof->domain_type  = XENOPROF_DOMAIN_IGNORED;
    2.57      d->xenoprof->domain_ready = 0;
    2.58 -    d->xenoprof->is_primary = is_primary;
    2.59 -
    2.60 -    xenoprof_init.is_primary = is_primary;
    2.61 -    xenoprof_init.num_events = num_events;
    2.62 -    xenoprof_init.nbuf = d->xenoprof->nbuf;
    2.63 -    xenoprof_init.bufsize = d->xenoprof->bufsize;
    2.64 -    xenoprof_init.buf_maddr = __pa(d->xenoprof->rawbuf);
    2.65 +    if ( primary_profiler == current->domain )
    2.66 +        d->xenoprof->is_primary = 1;
    2.67 +    else
    2.68 +        d->xenoprof->is_primary = 0;
    2.69 +        
    2.70 +    xenoprof_get_buffer.nbuf = d->xenoprof->nbuf;
    2.71 +    xenoprof_get_buffer.bufsize = d->xenoprof->bufsize;
    2.72 +    xenoprof_get_buffer.buf_maddr = __pa(d->xenoprof->rawbuf);
    2.73  
    2.74 -    if ( copy_to_guest(arg, &xenoprof_init, 1) )
    2.75 -    {
    2.76 -        ret = -EFAULT;
    2.77 -        goto err;
    2.78 -    }
    2.79 +    if ( copy_to_guest(arg, &xenoprof_get_buffer, 1) )
    2.80 +        return -EFAULT;
    2.81  
    2.82 -    return ret;
    2.83 -
    2.84 - err:
    2.85 -    if ( primary_profiler == current->domain )
    2.86 -        primary_profiler = NULL;
    2.87 -    return ret;
    2.88 +    return 0;
    2.89  }
    2.90  
    2.91  #define PRIV_OP(op) ( (op == XENOPROF_set_active)       \
    2.92 @@ -512,6 +517,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
    2.93          ret = xenoprof_op_init(arg);
    2.94          break;
    2.95  
    2.96 +    case XENOPROF_get_buffer:
    2.97 +        ret = xenoprof_op_get_buffer(arg);
    2.98 +        break;
    2.99 +
   2.100      case XENOPROF_reset_active_list:
   2.101      {
   2.102          reset_active_list();
     3.1 --- a/xen/include/public/xenoprof.h	Wed Sep 13 14:01:23 2006 +0100
     3.2 +++ b/xen/include/public/xenoprof.h	Wed Sep 13 14:05:33 2006 +0100
     3.3 @@ -28,6 +28,8 @@
     3.4  #define XENOPROF_disable_virq       11
     3.5  #define XENOPROF_release_counters   12
     3.6  #define XENOPROF_shutdown           13
     3.7 +#define XENOPROF_get_buffer         14
     3.8 +#define XENOPROF_last_op            14
     3.9  
    3.10  #define MAX_OPROF_EVENTS    32
    3.11  #define MAX_OPROF_DOMAINS   25	
    3.12 @@ -56,17 +58,22 @@ typedef struct xenoprof_buf xenoprof_buf
    3.13  DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);
    3.14  
    3.15  struct xenoprof_init {
    3.16 -    int32_t  max_samples;
    3.17      int32_t  num_events;
    3.18      int32_t  is_primary;
    3.19 -    int32_t  nbuf;
    3.20 -    int32_t  bufsize;
    3.21 -    uint64_t buf_maddr;
    3.22      char cpu_type[XENOPROF_CPU_TYPE_SIZE];
    3.23  };
    3.24  typedef struct xenoprof_init xenoprof_init_t;
    3.25  DEFINE_XEN_GUEST_HANDLE(xenoprof_init_t);
    3.26  
    3.27 +struct xenoprof_get_buffer {
    3.28 +    int32_t  max_samples;
    3.29 +    int32_t  nbuf;
    3.30 +    int32_t  bufsize;
    3.31 +    uint64_t buf_maddr;
    3.32 +};
    3.33 +typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
    3.34 +DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
    3.35 +
    3.36  struct xenoprof_counter {
    3.37      uint32_t ind;
    3.38      uint64_t count;