[libvirt] [PATCH] Add NUMA memory information to virsh capabilities output.

Daniel P. Berrange berrange at redhat.com
Wed Mar 6 22:07:27 UTC 2013


On Thu, Feb 14, 2013 at 12:52:38PM -0500, Dusty Mabe wrote:
> ---
>  docs/schemas/capability.rng               | 10 ++++
>  src/conf/capabilities.c                   |  8 +++
>  src/conf/capabilities.h                   |  2 +
>  src/nodeinfo.c                            | 64 +++++++++++++++++++++-
>  src/test/test_driver.c                    |  2 +-
>  src/xen/xend_internal.c                   |  2 +-
>  tests/capabilityschemadata/caps-test3.xml | 88 +++++++++++++++++++++++++++++++
>  7 files changed, 173 insertions(+), 3 deletions(-)
>  create mode 100644 tests/capabilityschemadata/caps-test3.xml
> 
> diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng
> index 53fb04a..e0396aa 100644
> --- a/docs/schemas/capability.rng
> +++ b/docs/schemas/capability.rng
> @@ -177,6 +177,10 @@
>        </attribute>
>  
>        <optional>
> +        <ref name='memory'/>
> +      </optional>
> +
> +      <optional>
>          <element name='cpus'>
>            <attribute name='num'>
>              <ref name='unsignedInt'/>
> @@ -189,6 +193,12 @@
>      </element>
>    </define>
>  
> +  <define name='memory'>
> +    <element name='memory'>
> +        <ref name='scaledInteger'/>
> +    </element>
> +  </define>
> +
>    <define name='cpu'>
>      <element name='cpu'>
>        <attribute name='id'>
> diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
> index a0e597b..9824f0c 100644
> --- a/src/conf/capabilities.c
> +++ b/src/conf/capabilities.c
> @@ -273,6 +273,7 @@ int
>  virCapabilitiesAddHostNUMACell(virCapsPtr caps,
>                                 int num,
>                                 int ncpus,
> +                               unsigned long long mem,
>                                 virCapsHostNUMACellCPUPtr cpus)
>  {
>      virCapsHostNUMACellPtr cell;
> @@ -286,6 +287,7 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
>  
>      cell->ncpus = ncpus;
>      cell->num = num;
> +    cell->mem = mem;
>      cell->cpus = cpus;
>  
>      caps->host.numaCell[caps->host.nnumaCell++] = cell;
> @@ -712,6 +714,12 @@ virCapabilitiesFormatNUMATopology(virBufferPtr xml,
>      virBufferAsprintf(xml, "      <cells num='%zu'>\n", ncells);
>      for (i = 0; i < ncells; i++) {
>          virBufferAsprintf(xml, "        <cell id='%d'>\n", cells[i]->num);
> +
> +        /* Print out the numacell memory total if it is available */
> +        if (cells[i]->mem)
> +        virBufferAsprintf(xml, "          <memory unit='KiB'>%llu</memory>\n",
> +                          cells[i]->mem);
> +
>          virBufferAsprintf(xml, "          <cpus num='%d'>\n", cells[i]->ncpus);
>          for (j = 0; j < cells[i]->ncpus; j++) {
>              virBufferAsprintf(xml, "            <cpu id='%d'",
> diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
> index cc01765..6c67fb3 100644
> --- a/src/conf/capabilities.h
> +++ b/src/conf/capabilities.h
> @@ -99,6 +99,7 @@ typedef virCapsHostNUMACell *virCapsHostNUMACellPtr;
>  struct _virCapsHostNUMACell {
>      int num;
>      int ncpus;
> +    unsigned long long mem; /* in kibibytes */
>      virCapsHostNUMACellCPUPtr cpus;
>  };
>  
> @@ -210,6 +211,7 @@ extern int
>  virCapabilitiesAddHostNUMACell(virCapsPtr caps,
>                                 int num,
>                                 int ncpus,
> +                               unsigned long long mem,
>                                 virCapsHostNUMACellCPUPtr cpus);
>  
>  
> diff --git a/src/nodeinfo.c b/src/nodeinfo.c
> index 1622322..f9e173b 100644
> --- a/src/nodeinfo.c
> +++ b/src/nodeinfo.c
> @@ -102,6 +102,7 @@ static int linuxNodeGetMemoryStats(FILE *meminfo,
>                                     int cellNum,
>                                     virNodeMemoryStatsPtr params,
>                                     int *nparams);
> +static unsigned long long nodeGetCellMemory(int cell);
>  
>  /* Return the positive decimal contents of the given
>   * DIR/cpu%u/FILE, or -1 on error.  If DEFAULT_VALUE is non-negative
> @@ -1531,6 +1532,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
>      int n;
>      unsigned long *mask = NULL;
>      unsigned long *allonesmask = NULL;
> +    unsigned long long memory;
>      virCapsHostNUMACellCPUPtr cpus = NULL;
>      int ret = -1;
>      int max_n_cpus = NUMA_MAX_N_CPUS;
> @@ -1562,6 +1564,11 @@ nodeCapsInitNUMA(virCapsPtr caps)
>              continue;
>          }
>  
> +        /* Detect the amount of memory in the numa cell */
> +        memory = nodeGetCellMemory(n);
> +        if (memory == 0)
> +            goto cleanup;
> +
>          for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++)
>              if (MASK_CPU_ISSET(mask, i))
>                  ncpus++;
> @@ -1578,7 +1585,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
>              }
>          }
>  
> -        if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, cpus) < 0)
> +        if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, memory, cpus) < 0)
>              goto cleanup;
>      }
>  
> @@ -1665,6 +1672,54 @@ cleanup:
>      return freeMem;
>  }
>  
> +/**
> + * nodeGetCellMemory
> + * @cell: The number of the numa cell to get memory info for.
> + *
> + * Will call the numa_node_size64() function from libnuma to get
> + * the amount of total memory in bytes. It is then converted to
> + * KiB and returned.
> + *
> + * Returns 0 on failure, amount of memory in KiB on success.
> + */
> +static unsigned long long nodeGetCellMemory(int cell)
> +{
> +    long long mem;
> +    unsigned long long memKiB = 0;
> +    int maxCell;
> +
> +    if (numa_available() < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       "%s", _("NUMA not supported on this host"));
> +        goto cleanup;
> +    }

This check isn't needed since you're calling this from
nodeInitNUMA which has already done exactly this check

> +
> +    /* Make sure the provided cell number is valid. */
> +    maxCell = numa_max_node();
> +    if (cell > maxCell) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("cell %d out of range (0-%d)"),
> +                       cell, maxCell);
> +        goto cleanup;
> +    }
> +
> +    /* Get the amount of memory(bytes) in the node */
> +    mem = numa_node_size64(cell, NULL);
> +    if (mem < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Failed to query NUMA total memory for node: %d"),
> +                       cell);
> +        goto cleanup;
> +    }
> +
> +    /* Convert the memory from bytes to KiB */
> +    memKiB = mem >> 10;

What do people think about bytes vs kb for the capabilities XML.
I can go either way really. Bytes is more precise, but I doubt
apps will care about bytes when we're talking multiple GB of
RAM.

> +
> +cleanup:
> +    return memKiB;
> +}
> +
> +


ACK to the patch with the small change made.

Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list