[libvirt] [RFC PATCH v1 2/4] libxl: vnuma support

Jim Fehlig jfehlig at suse.com
Mon Jun 19 20:55:37 UTC 2017


On 06/12/2017 12:54 PM, Wim Ten Have wrote:
> From: Wim ten Have <wim.ten.have at oracle.com>
>
> This patch generates a NUMA distance-aware libxl description from the
> information extracted from a NUMA distance-aware libvirt XML file.
>
> By default, if no NUMA node distance information is supplied in the
> libvirt XML file, this patch uses the distances 10 for local and 21 for
> remote nodes/sockets."
>
> Signed-off-by: Wim ten Have <wim.ten.have at oracle.com>
> ---
>  src/libxl/libxl_conf.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 128 insertions(+)
>
> diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
> index 04d9dd1..3e1a759 100644
> --- a/src/libxl/libxl_conf.c
> +++ b/src/libxl/libxl_conf.c
> @@ -617,6 +617,129 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
>      return 0;
>  }
>
> +#ifdef LIBXL_HAVE_VNUMA
> +static int
> +libxlMakeVnumaList(
> +    virDomainDefPtr def,
> +    libxl_ctx *ctx,
> +    libxl_domain_config *d_config)

The usual pattern is

static int
libxlMakeVnumaList(virDomainDefPtr def,
                    libxl_ctx *ctx,
                    libxl_domain_config *d_config)

> +{
> +    int ret = -1;
> +    char *vcpus = NULL;
> +    size_t i, j;
> +    size_t nr_nodes;
> +    size_t num_vnuma;
> +    virDomainNumaPtr numa = def->numa;
> +    libxl_domain_build_info *b_info = &d_config->b_info;
> +    libxl_physinfo physinfo;
> +    libxl_vnode_info *vnuma_nodes = NULL;
> +
> +    if (!numa)
> +        return 0;
> +
> +    num_vnuma = virDomainNumaGetNodeCount(numa);
> +    if (!num_vnuma)
> +        return 0;
> +
> +    libxl_physinfo_init(&physinfo);
> +    if (libxl_get_physinfo(ctx, &physinfo) < 0) {
> +        libxl_physinfo_dispose(&physinfo);
> +        VIR_WARN("libxl_get_physinfo failed");

The function, and hence domain startup, is going to fail, so we'll need proper 
error reporting here.

> +        goto cleanup;
> +    }
> +    nr_nodes = physinfo.nr_nodes;
> +    libxl_physinfo_dispose(&physinfo);
> +
> +    if (num_vnuma > nr_nodes) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                       _("Number of configured numa cells %zu exceeds the physical available nodes %zu"),
> +                       num_vnuma, nr_nodes);
> +        goto cleanup;
> +    }
> +
> +    /*
> +     * allocate the vnuma_nodes for assignment under b_info.
> +     */
> +    if (VIR_ALLOC_N(vnuma_nodes, num_vnuma) < 0)
> +        goto cleanup;
> +
> +    /*
> +     * parse the vnuma vnodes data.
> +     */
> +    for (i = 0; i < num_vnuma; i++) {
> +        int cpu;
> +        virBitmapPtr bitmap = NULL;
> +        libxl_bitmap vcpu_bitmap;
> +        libxl_vnode_info *p = &vnuma_nodes[i];
> +
> +        libxl_vnode_info_init(p);
> +
> +        /* pnode */
> +        p->pnode = i;
> +
> +        /* memory size */
> +        p->memkb = virDomainNumaGetNodeMemorySize(numa, i);
> +
> +        /* vcpus */
> +        vcpus = virBitmapFormat(virDomainNumaGetNodeCpumask(numa, i));
> +        if (vcpus == NULL) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR,
> +                           _("vnuma sibling %zu missing vcpus set"), i);
> +            goto cleanup;
> +        }
> +
> +        if (virBitmapParse(vcpus, &bitmap, VIR_DOMAIN_CPUMASK_LEN) < 0)
> +            goto cleanup;

Why the need to format and parse the bitmap returned by 
virtDomainNumaGetNodeCpumask? Can it be used directly where 'bitmap' is used below?

> +
> +        if ((cpu = virBitmapNextSetBit(bitmap, -1)) < 0) {
> +            VIR_FREE(bitmap);
> +            goto cleanup;
> +        }
> +
> +        libxl_bitmap_init(&vcpu_bitmap);
> +        if (libxl_cpu_bitmap_alloc(ctx, &vcpu_bitmap, b_info->max_vcpus)) {
> +            virReportOOMError();

It looks like 'bitmap' will leak on this error path.

> +            goto cleanup;
> +        }
> +
> +        do {
> +            libxl_bitmap_set(&vcpu_bitmap, cpu);
> +        } while ((cpu = virBitmapNextSetBit(bitmap, cpu)) >= 0);
> +
> +        libxl_bitmap_copy_alloc(ctx, &p->vcpus, &vcpu_bitmap);
> +        libxl_bitmap_dispose(&vcpu_bitmap);
> +
> +        VIR_FREE(bitmap);
> +        VIR_FREE(vcpus);

'vcpus' is freed in cleanup.

> +
> +        /* vdistances */
> +        if (VIR_ALLOC_N(p->distances, num_vnuma) < 0)
> +            goto cleanup;
> +        p->num_distances = num_vnuma;
> +
> +        /*
> +         * Apply the configured distance value. If not
> +         * available set 10 for local or 21 for remote nodes.
> +         */
> +        for (j = 0; j < num_vnuma; j++)
> +            p->distances[j] = virDomainNumaGetNodeDistance(numa, i, j) ?:
> +                                (i == j ? 10 : 21);

Is the '?:' shorthand a GNU extension? I could only find one other use of it in 
the codebase, in src/vz/vz_sdk.c. I like the concise form, but also fear it is 
difficult to read.

Regards,
Jim

> +    }
> +
> +    b_info->vnuma_nodes = vnuma_nodes;
> +    b_info->num_vnuma_nodes = num_vnuma;
> +
> +    ret = 0;
> +
> + cleanup:
> +    if (ret)
> +        VIR_FREE(vnuma_nodes);
> +    VIR_FREE(vcpus);
> +
> +    return ret;
> +}
> +#endif
> +
>  static int
>  libxlDiskSetDiscard(libxl_device_disk *x_disk, int discard)
>  {
> @@ -2207,6 +2330,11 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
>      if (libxlMakeDomBuildInfo(def, ctx, caps, d_config) < 0)
>          return -1;
>
> +#ifdef LIBXL_HAVE_VNUMA
> +    if (libxlMakeVnumaList(def, ctx, d_config) < 0)
> +        return -1;
> +#endif
> +
>      if (libxlMakeDiskList(def, d_config) < 0)
>          return -1;
>
>




More information about the libvir-list mailing list