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

Re: [Xen-devel] [PATCH v5 7/8] libxl/libxc: Move libxl_get_numainfo()'s hypercall buffer management to libxc



On Thu, Mar 19, 2015 at 05:54:03PM -0400, Boris Ostrovsky wrote:
> xc_numainfo() is not expected to be used on a hot path and therefore
> hypercall buffer management can be pushed into libxc. This will simplify
> life for callers.
> 
> Also update error logging macros.
> 
> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
> ---
> Changes in v5:
> * Adjust to new interface (as described in changelog for patch 4/8)
> 
>  tools/libxc/include/xenctrl.h     |    4 ++-
>  tools/libxc/xc_misc.c             |   41 ++++++++++++++++++++++++-----
>  tools/libxl/libxl.c               |   52 
> ++++++++++++-------------------------
>  tools/python/xen/lowlevel/xc/xc.c |   38 ++++++++++-----------------
>  4 files changed, 68 insertions(+), 67 deletions(-)
> 
> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
> index 14d22ce..54540e7 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -1228,6 +1228,7 @@ int xc_send_debug_keys(xc_interface *xch, char *keys);
>  typedef xen_sysctl_physinfo_t xc_physinfo_t;
>  typedef xen_sysctl_cputopo_t xc_cputopo_t;
>  typedef xen_sysctl_numainfo_t xc_numainfo_t;
> +typedef xen_sysctl_meminfo_t xc_meminfo_t;
>  
>  typedef uint32_t xc_cpu_to_node_t;
>  typedef uint32_t xc_cpu_to_socket_t;
> @@ -1239,7 +1240,8 @@ typedef uint32_t xc_node_to_node_dist_t;
>  int xc_physinfo(xc_interface *xch, xc_physinfo_t *info);
>  int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
>                     xc_cputopo_t *cputopo);
> -int xc_numainfo(xc_interface *xch, xc_numainfo_t *info);
> +int xc_numainfo(xc_interface *xch, unsigned *max_nodes,
> +                xc_meminfo_t *meminfo, uint32_t *distance);
>  
>  int xc_sched_id(xc_interface *xch,
>                  int *sched_id);
> diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
> index 411128e..607ae61 100644
> --- a/tools/libxc/xc_misc.c
> +++ b/tools/libxc/xc_misc.c
> @@ -209,22 +209,49 @@ out:
>      return ret;
>  }
>  
> -int xc_numainfo(xc_interface *xch,
> -                xc_numainfo_t *put_info)
> +int xc_numainfo(xc_interface *xch, unsigned *max_nodes,
> +                xc_meminfo_t *meminfo, uint32_t *distance)
>  {
>      int ret;
>      DECLARE_SYSCTL;
> +    DECLARE_HYPERCALL_BOUNCE(meminfo, *max_nodes * sizeof(*meminfo),
> +                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
> +    DECLARE_HYPERCALL_BOUNCE(distance,
> +                             *max_nodes * *max_nodes * sizeof(*distance),
> +                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
>  
> -    sysctl.cmd = XEN_SYSCTL_numainfo;
> +    if (meminfo && distance) {

The syntax in xc_misc.c looks mostly to be of the
'if ( meminfo && distance )
 {
' type.

> +        if ((ret = xc_hypercall_bounce_pre(xch, meminfo)))
> +            goto out;
> +        if ((ret = xc_hypercall_bounce_pre(xch, distance)))
> +            goto out;
>  
> -    memcpy(&sysctl.u.numainfo, put_info, sizeof(*put_info));
> +        sysctl.u.numainfo.num_nodes = *max_nodes;
> +        set_xen_guest_handle(sysctl.u.numainfo.meminfo, meminfo);
> +        set_xen_guest_handle(sysctl.u.numainfo.distance, distance);
> +    } else if (meminfo || distance) {
> +        errno = EINVAL;
> +        return -1;
> +    } else {
> +        set_xen_guest_handle(sysctl.u.numainfo.meminfo,
> +                             HYPERCALL_BUFFER_NULL);
> +        set_xen_guest_handle(sysctl.u.numainfo.distance,
> +                             HYPERCALL_BUFFER_NULL);
> +    }
>  
> +    sysctl.cmd = XEN_SYSCTL_numainfo;
>      if ((ret = do_sysctl(xch, &sysctl)) != 0)
> -        return ret;
> +        goto out;
>  
> -    memcpy(put_info, &sysctl.u.numainfo, sizeof(*put_info));
> +    *max_nodes = sysctl.u.numainfo.num_nodes;
>  
> -    return 0;
> +out:
> +    if (meminfo && distance) {
> +        xc_hypercall_bounce_post(xch, meminfo);
> +        xc_hypercall_bounce_post(xch, distance);
> +    }
> +
> +    return ret;
>  }
>  
>  
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index 2b7d19c..ee97a54 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -5094,62 +5094,44 @@ libxl_cputopology *libxl_get_cpu_topology(libxl_ctx 
> *ctx, int *nb_cpu_out)
>  libxl_numainfo *libxl_get_numainfo(libxl_ctx *ctx, int *nr)
>  {
>      GC_INIT(ctx);
> -    xc_numainfo_t ninfo;
> -    DECLARE_HYPERCALL_BUFFER(xen_sysctl_meminfo_t, meminfo);
> -    DECLARE_HYPERCALL_BUFFER(uint32_t, distance);
> +    xc_meminfo_t *meminfo;
> +    uint32_t *distance;
>      libxl_numainfo *ret = NULL;
>      int i, j;
> +    unsigned num_nodes;
>  
> -    set_xen_guest_handle(ninfo.meminfo, HYPERCALL_BUFFER_NULL);
> -    set_xen_guest_handle(ninfo.distance, HYPERCALL_BUFFER_NULL);
> -    if ( xc_numainfo(ctx->xch, &ninfo) != 0)
> -    {
> -        LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of NODES");
> -        ret = NULL;
> +    if (xc_numainfo(ctx->xch, &num_nodes, NULL, NULL)) {

I think for this one you need 'if ( xc_numa.. )
 {'

> +        LOGEV(ERROR, errno, "Unable to determine number of nodes");
>          goto out;
>      }
>  
> -    meminfo = xc_hypercall_buffer_alloc(ctx->xch, meminfo,
> -                                        sizeof(*meminfo) * ninfo.num_nodes);
> -    distance = xc_hypercall_buffer_alloc(ctx->xch, distance,
> -                                         sizeof(*distance) *
> -                                         ninfo.num_nodes * ninfo.num_nodes);
> -    if ((meminfo == NULL) || (distance == NULL)) {
> -        LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM,
> -                            "Unable to allocate hypercall arguments");
> -        goto fail;
> -    }
> +    meminfo = libxl__zalloc(gc, sizeof(*meminfo) * num_nodes);
> +    distance = libxl__zalloc(gc, sizeof(*distance) * num_nodes * num_nodes);
>  
> -    set_xen_guest_handle(ninfo.meminfo, meminfo);
> -    set_xen_guest_handle(ninfo.distance, distance);
> -    if (xc_numainfo(ctx->xch, &ninfo) != 0) {
> -        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting numainfo");
> -        goto fail;
> +    if (xc_numainfo(ctx->xch, &num_nodes, meminfo, distance)) {
> +        LOGEV(ERROR, errno, "getting numainfo");

Ditto
> +        goto out;
>      }
>  
> -    *nr = ninfo.num_nodes;
> +    *nr = num_nodes;
>  
> -    ret = libxl__zalloc(NOGC, sizeof(libxl_numainfo) * ninfo.num_nodes);
> -    for (i = 0; i < ninfo.num_nodes; i++)
> -        ret[i].dists = libxl__calloc(NOGC, ninfo.num_nodes, 
> sizeof(*distance));
> +    ret = libxl__zalloc(NOGC, sizeof(libxl_numainfo) * num_nodes);
> +    for (i = 0; i < num_nodes; i++)
> +        ret[i].dists = libxl__calloc(NOGC, num_nodes, sizeof(*distance));
>  
> -    for (i = 0; i < ninfo.num_nodes; i++) {
> +    for (i = 0; i < num_nodes; i++) {
>  #define V(val, invalid) (val == invalid) ? \
>         LIBXL_NUMAINFO_INVALID_ENTRY : val
>          ret[i].size = V(meminfo[i].memsize, XEN_INVALID_MEM_SZ);
>          ret[i].free = V(meminfo[i].memfree, XEN_INVALID_MEM_SZ);
> -        ret[i].num_dists = ninfo.num_nodes;
> +        ret[i].num_dists = num_nodes;
>          for (j = 0; j < ret[i].num_dists; j++) {
> -            unsigned idx = i * ninfo.num_nodes + j;
> +            unsigned idx = i * num_nodes + j;
>              ret[i].dists[j] = V(distance[idx], XEN_INVALID_NODE_DIST);
>          }
>  #undef V
>      }
>  
> - fail:
> -    xc_hypercall_buffer_free(ctx->xch, meminfo);
> -    xc_hypercall_buffer_free(ctx->xch, distance);
> -
>   out:
>      GC_FREE;
>      return ret;
> diff --git a/tools/python/xen/lowlevel/xc/xc.c 
> b/tools/python/xen/lowlevel/xc/xc.c
> index 21ba57d..fbd93db 100644
> --- a/tools/python/xen/lowlevel/xc/xc.c
> +++ b/tools/python/xen/lowlevel/xc/xc.c
> @@ -1293,33 +1293,23 @@ out:
>  
>  static PyObject *pyxc_numainfo(XcObject *self)
>  {
> -    xc_numainfo_t ninfo = { 0 };
> -    unsigned i, j;
> +    unsigned i, j, num_nodes;
>      uint64_t free_heap;
>      PyObject *ret_obj = NULL, *node_to_node_dist_list_obj;
>      PyObject *node_to_memsize_obj, *node_to_memfree_obj;
>      PyObject *node_to_dma32_mem_obj, *node_to_node_dist_obj;
> -    DECLARE_HYPERCALL_BUFFER(xen_sysctl_meminfo_t, meminfo);
> -    DECLARE_HYPERCALL_BUFFER(uint32_t, distance);
> +    xc_meminfo_t *meminfo = NULL;
> +    uint32_t *distance = NULL;
>  
> -    set_xen_guest_handle(ninfo.meminfo, HYPERCALL_BUFFER_NULL);
> -    set_xen_guest_handle(ninfo.distance, HYPERCALL_BUFFER_NULL);
> -    if ( xc_numainfo(self->xc_handle, &ninfo) != 0 )
> +    if ( xc_numainfo(self->xc_handle, &num_nodes, NULL, NULL) != 0 )
>          goto out;
>  
> -    meminfo = xc_hypercall_buffer_alloc(self->xc_handle, meminfo,
> -                                        sizeof(*meminfo) * ninfo.num_nodes);
> -    if ( meminfo == NULL )
> -        goto out;
> -    distance = xc_hypercall_buffer_alloc(self->xc_handle, distance,
> -                                         sizeof(*distance) *
> -                                         ninfo.num_nodes * ninfo.num_nodes);
> -    if ( distance == NULL )
> +    meminfo = calloc(num_nodes, sizeof(*meminfo));
> +    distance = calloc(num_nodes * num_nodes, sizeof(*distance));
> +    if ( (meminfo == NULL) || (distance == NULL) )
>          goto out;
>  
> -    set_xen_guest_handle(ninfo.meminfo, meminfo);
> -    set_xen_guest_handle(ninfo.distance, distance);
> -    if ( xc_numainfo(self->xc_handle, &ninfo) != 0 )
> +    if ( xc_numainfo(self->xc_handle, &num_nodes, meminfo, distance) != 0 )
>          goto out;
>  
>      /* Construct node-to-* lists. */
> @@ -1327,7 +1317,7 @@ static PyObject *pyxc_numainfo(XcObject *self)
>      node_to_memfree_obj = PyList_New(0);
>      node_to_dma32_mem_obj = PyList_New(0);
>      node_to_node_dist_list_obj = PyList_New(0);
> -    for ( i = 0; i < ninfo.num_nodes; i++ )
> +    for ( i = 0; i < num_nodes; i++ )
>      {
>          PyObject *pyint;
>          unsigned invalid_node;
> @@ -1351,9 +1341,9 @@ static PyObject *pyxc_numainfo(XcObject *self)
>          /* Node to Node Distance */
>          node_to_node_dist_obj = PyList_New(0);
>          invalid_node = (meminfo[i].memsize == XEN_INVALID_MEM_SZ);
> -        for ( j = 0; j < ninfo.num_nodes; j++ )
> +        for ( j = 0; j < num_nodes; j++ )
>          {
> -            uint32_t dist = distance[i * ninfo.num_nodes + j];
> +            uint32_t dist = distance[i * num_nodes + j];
>              if ( invalid_node || (dist == XEN_INVALID_NODE_DIST) )
>              {
>                  PyList_Append(node_to_node_dist_obj, Py_None);
> @@ -1369,7 +1359,7 @@ static PyObject *pyxc_numainfo(XcObject *self)
>          Py_DECREF(node_to_node_dist_obj);
>      }
>  
> -    ret_obj = Py_BuildValue("{s:i}", "max_node_index", ninfo.num_nodes + 1);
> +    ret_obj = Py_BuildValue("{s:i}", "max_node_index", num_nodes + 1);
>  
>      PyDict_SetItemString(ret_obj, "node_memsize", node_to_memsize_obj);
>      Py_DECREF(node_to_memsize_obj);
> @@ -1385,8 +1375,8 @@ static PyObject *pyxc_numainfo(XcObject *self)
>      Py_DECREF(node_to_node_dist_list_obj);
>  
>  out:
> -    xc_hypercall_buffer_free(self->xc_handle, meminfo);
> -    xc_hypercall_buffer_free(self->xc_handle, distance);
> +    free(meminfo);
> +    free(distance);
>      return ret_obj ? ret_obj : pyxc_error_to_exception(self->xc_handle);
>  }
>  
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel

_______________________________________________
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®.