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

Re: [Xen-devel] [PATCH v3 1/2] libxc/xentrace: Replace xc_tbuf_set_cpu_mask with CPU mask with xc_cpumap_t instead of uint32_t



On Fri, 2014-06-20 at 15:33 -0400, Konrad Rzeszutek Wilk wrote:
> We replace the implementation of xc_tbuf_set_cpu_mask with
> an xc_cpumap_t instead of a uint32_t. This means we can use an
> arbitrary bitmap without being limited to the 32-bits as
> previously we were. Furthermore since there is only one
> user of xc_tbuf_set_cpu_mask we just replace it and
> its user in one go.
> 
> We also add an macro which can be used by both libxc and
> xentrace.
> 
> And update the man page to describe this behavior.
> 
> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>

For the libxc bits: Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

> ---
>  tools/libxc/xc_tbuf.c     |   26 +++++++-----
>  tools/libxc/xenctrl.h     |    7 +++-
>  tools/xentrace/xentrace.8 |    3 +
>  tools/xentrace/xentrace.c |   97 
> ++++++++++++++++++++++++++++++++++++++-------
>  4 files changed, 107 insertions(+), 26 deletions(-)
> 
> diff --git a/tools/libxc/xc_tbuf.c b/tools/libxc/xc_tbuf.c
> index 8777492..d54da8a 100644
> --- a/tools/libxc/xc_tbuf.c
> +++ b/tools/libxc/xc_tbuf.c
> @@ -113,15 +113,23 @@ int xc_tbuf_disable(xc_interface *xch)
>      return tbuf_enable(xch, 0);
>  }
>  
> -int xc_tbuf_set_cpu_mask(xc_interface *xch, uint32_t mask)
> +int xc_tbuf_set_cpu_mask(xc_interface *xch, xc_cpumap_t mask, int bits)
>  {
>      DECLARE_SYSCTL;
> -    DECLARE_HYPERCALL_BUFFER(uint8_t, bytemap);
> +    DECLARE_HYPERCALL_BOUNCE(mask, XC_DIV_ROUND_UP(bits, 8), 
> XC_HYPERCALL_BUFFER_BOUNCE_IN);
>      int ret = -1;
> -    uint64_t mask64 = mask;
> +    int local_bits;
>  
> -    bytemap = xc_hypercall_buffer_alloc(xch, bytemap, sizeof(mask64));
> -    if ( bytemap == NULL )
> +    if ( bits <= 0 )
> +        goto out;
> +
> +    local_bits = xc_get_max_cpus(xch);
> +    if ( bits > local_bits )
> +    {
> +        PERROR("Wrong amount of bits supplied: %d > %d!\n", bits, 
> local_bits);
> +        goto out;
> +    }
> +    if ( xc_hypercall_bounce_pre(xch, mask) )
>      {
>          PERROR("Could not allocate memory for xc_tbuf_set_cpu_mask 
> hypercall");
>          goto out;
> @@ -131,14 +139,12 @@ int xc_tbuf_set_cpu_mask(xc_interface *xch, uint32_t 
> mask)
>      sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION;
>      sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_set_cpu_mask;
>  
> -    bitmap_64_to_byte(bytemap, &mask64, sizeof (mask64) * 8);
> -
> -    set_xen_guest_handle(sysctl.u.tbuf_op.cpu_mask.bitmap, bytemap);
> -    sysctl.u.tbuf_op.cpu_mask.nr_bits = sizeof(bytemap) * 8;
> +    set_xen_guest_handle(sysctl.u.tbuf_op.cpu_mask.bitmap, mask);
> +    sysctl.u.tbuf_op.cpu_mask.nr_bits = bits;
>  
>      ret = do_sysctl(xch, &sysctl);
>  
> -    xc_hypercall_buffer_free(xch, bytemap);
> +    xc_hypercall_bounce_post(xch, mask);
>  
>   out:
>      return ret;
> diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
> index b55d857..b378312 100644
> --- a/tools/libxc/xenctrl.h
> +++ b/tools/libxc/xenctrl.h
> @@ -1449,6 +1449,11 @@ int xc_availheap(xc_interface *xch, int min_width, int 
> max_width, int node,
>   */
>  
>  /**
> + * Useful macro for converting byte arrays to bitmaps.
> + */
> +#define XC_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
> +
> +/**
>   * xc_tbuf_enable - enable tracing buffers
>   *
>   * @parm xch a handle to an open hypervisor interface
> @@ -1489,7 +1494,7 @@ int xc_tbuf_set_size(xc_interface *xch, unsigned long 
> size);
>   */
>  int xc_tbuf_get_size(xc_interface *xch, unsigned long *size);
>  
> -int xc_tbuf_set_cpu_mask(xc_interface *xch, uint32_t mask);
> +int xc_tbuf_set_cpu_mask(xc_interface *xch, xc_cpumap_t mask, int bits);
>  
>  int xc_tbuf_set_evt_mask(xc_interface *xch, uint32_t mask);
>  
> diff --git a/tools/xentrace/xentrace.8 b/tools/xentrace/xentrace.8
> index ac18e9f..c176a96 100644
> --- a/tools/xentrace/xentrace.8
> +++ b/tools/xentrace/xentrace.8
> @@ -38,6 +38,9 @@ for new data.
>  .TP
>  .B -c, --cpu-mask=c
>  set bitmask of CPUs to trace. It is limited to 32-bits.
> +If not specified, the cpu-mask of all of the available CPUs will be
> +constructed.
> +
>  .TP
>  .B -e, --evt-mask=e
>  set event capture mask. If not specified the TRC_ALL will be used.
> diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c
> index 8a38e32..ee1d021 100644
> --- a/tools/xentrace/xentrace.c
> +++ b/tools/xentrace/xentrace.c
> @@ -52,7 +52,7 @@ typedef struct settings_st {
>      char *outfile;
>      unsigned long poll_sleep; /* milliseconds to sleep between polls */
>      uint32_t evt_mask;
> -    uint32_t cpu_mask;
> +    xc_cpumap_t cpu_mask;
>      unsigned long tbuf_size;
>      unsigned long disk_rsvd;
>      unsigned long timeout;
> @@ -521,23 +521,66 @@ static struct t_struct *map_tbufs(unsigned long 
> tbufs_mfn, unsigned int num,
>      return &tbufs;
>  }
>  
> +void print_cpu_mask(xc_cpumap_t mask, int bits)
> +{
> +    unsigned int v, had_printed = 0;
> +    int i;
> +
> +    fprintf(stderr, "change cpumask to 0x");
> +
> +    for ( i = XC_DIV_ROUND_UP(bits, 8); i >= 0; i-- )
> +    {
> +        v = mask[i];
> +        if ( v || had_printed || !i ) {
> +            fprintf(stderr,"%x", v);
> +            had_printed = 1;
> +        }
> +   }
> +   fprintf(stderr, "\n");
> +}
> +
> +static void set_cpu_mask(xc_cpumap_t mask)
> +{
> +    int bits, i, ret = 0;
> +
> +    bits = xc_get_max_cpus(xc_handle);
> +    if ( bits <= 0 )
> +        goto out;
> +
> +    if ( !mask )
> +    {
> +        mask = xc_cpumap_alloc(xc_handle);
> +        if ( !mask )
> +            goto out;
> +
> +        /* Set it to include _all_ CPUs. */
> +        for ( i = 0; i < XC_DIV_ROUND_UP(bits, 8); i++ )
> +            mask[i] = 0xff;
> +    }
> +    /* And this will limit it to the exact amount of bits. */
> +    ret = xc_tbuf_set_cpu_mask(xc_handle, mask, bits);
> +    if ( ret != 0 )
> +        goto out;
> +
> +    print_cpu_mask(mask, bits);
> +    return;
> +out:
> +    PERROR("Failure to get trace buffer pointer from Xen and set the new 
> mask");
> +    exit(EXIT_FAILURE);
> +}
> +
>  /**
> - * set_mask - set the cpu/event mask in HV
> + * set_mask - set the event mask in HV
>   * @mask:           the new mask 
>   * @type:           the new mask type,0-event mask, 1-cpu mask
>   *
>   */
> -static void set_mask(uint32_t mask, int type)
> +static void set_evt_mask(uint32_t mask)
>  {
>      int ret = 0;
>  
> -    if (type == 1) {
> -        ret = xc_tbuf_set_cpu_mask(xc_handle, mask);
> -        fprintf(stderr, "change cpumask to 0x%x\n", mask);
> -    } else if (type == 0) {
> -        ret = xc_tbuf_set_evt_mask(xc_handle, mask);
> -        fprintf(stderr, "change evtmask to 0x%x\n", mask);
> -    }
> +    ret = xc_tbuf_set_evt_mask(xc_handle, mask);
> +    fprintf(stderr, "change evtmask to 0x%x\n", mask);
>  
>      if ( ret != 0 )
>      {
> @@ -906,6 +949,23 @@ static int parse_evtmask(char *arg)
>      return 0;
>  }
>  
> +static int parse_cpumask(const char *arg)
> +{
> +    xc_cpumap_t map;
> +    uint32_t v, i;
> +
> +    map = malloc(sizeof(uint32_t));
> +    if ( !map )
> +        return -ENOMEM;
> +
> +    v = argtol(arg, 0);
> +    for ( i = 0; i < sizeof(uint32_t); i++ )
> +        map[i] = (v >> (i * 8)) & 0xff;
> +
> +    opts.cpu_mask = map;
> +    return 0;
> +}
> +
>  /* parse command line arguments */
>  static void parse_args(int argc, char **argv)
>  {
> @@ -937,7 +997,12 @@ static void parse_args(int argc, char **argv)
>              break;
>  
>          case 'c': /* set new cpu mask for filtering*/
> -            opts.cpu_mask = argtol(optarg, 0);
> +            /* Set opts.cpu_mask later as we don't have 'xch' set yet. */
> +            if ( parse_cpumask(optarg) )
> +            {
> +                perror("Not enough memory!");
> +                exit(EXIT_FAILURE);
> +            }
>              break;
>          
>          case 'e': /* set new event mask for filtering*/
> @@ -1002,7 +1067,7 @@ int main(int argc, char **argv)
>      opts.outfile = 0;
>      opts.poll_sleep = POLL_SLEEP_MILLIS;
>      opts.evt_mask = 0;
> -    opts.cpu_mask = 0;
> +    opts.cpu_mask = NULL;
>      opts.disk_rsvd = 0;
>      opts.disable_tracing = 1;
>      opts.start_disabled = 0;
> @@ -1018,10 +1083,12 @@ int main(int argc, char **argv)
>      }
>  
>      if ( opts.evt_mask != 0 )
> -        set_mask(opts.evt_mask, 0);
> +        set_evt_mask(opts.evt_mask);
> +
>  
> -    if ( opts.cpu_mask != 0 )
> -        set_mask(opts.cpu_mask, 1);
> +    set_cpu_mask(opts.cpu_mask);
> +    /* We don't use it pass this point. */
> +    free(opts.cpu_mask);
>  
>      if ( opts.timeout != 0 ) 
>          alarm(opts.timeout);



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.