[libvirt] [PATCH 2/3] Numa : Allow specification of 'units' for numa nodes.

Michal Privoznik mprivozn at redhat.com
Wed Nov 5 15:10:48 UTC 2014


On 05.11.2014 12:06, Prerna Saxena wrote:
>
>>From 7fe8487c5e8d24086637d2157bad25322b3654f7 Mon Sep 17 00:00:00 2001
> From: Prerna Saxena <prerna at linux.vnet.ibm.com>
> Date: Mon, 3 Nov 2014 07:53:59 +0530
>
>
> CPU numa topology implicitly allows memory specification in 'KiB'.
>
> Enabling this to accept the 'unit' in which memory needs to be specified.
> This now allows users to specify memory in units of choice, and
> lists the same in 'KiB' -- just like other 'memory' elements in XML.
>
>      <numa>
>        <cell cpus='0-3' memory='1024' unit='MiB' />
>        <cell cpus='4-7' memory='1024' unit='MiB' />
>      </numa>
>
> I wanted to use virDomainParseScaledValue(), but that function
> implicitly assumes an XML layout where 'memory' is an _element_ of type
> 'scaledInteger', with 'unit' as its attribute.
> A NUMA cell has XML specification where 'memory' is an _attribute_ of
> element 'cell'. Since changing XML layout is not an option, I have borrowed code from the same.

Yeah, I did the same in virDomainHugepagesParseXML. Maybe you can rename 
it to something more generic and reuse it here?

>
> Looking forward to suggestions on how this can best be done.
>
> Signed-off-by: Prerna Saxena <prerna at linux.vnet.ibm.com>
> ---
>   docs/schemas/domaincommon.rng |  5 +++++
>   src/conf/cpu_conf.c           | 36 ++++++++++++++++++++++++++++++++++--
>   2 files changed, 39 insertions(+), 2 deletions(-)
>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 20d81ae..44cabad 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -4144,6 +4144,11 @@
>           <ref name="memoryKB"/>
>         </attribute>
>         <optional>
> +        <attribute name="unit">
> +          <ref name="unit"/>
> +        </attribute>
> +      </optional>
> +      <optional>

Any XML change requires docs update. I can't ACK this with lacking 
documentation, sorry.

>           <attribute name="memAccess">
>             <choice>
>               <value>shared</value>
> diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
> index 5475c07..65b9815 100644
> --- a/src/conf/cpu_conf.c
> +++ b/src/conf/cpu_conf.c
> @@ -189,6 +189,7 @@ virCPUDefParseXML(xmlNodePtr node,
>       char *cpuMode;
>       char *fallback = NULL;
>       char *vendor_id = NULL;
> +    unsigned long long max;
>
>       if (!xmlStrEqual(node->name, BAD_CAST "cpu")) {
>           virReportError(VIR_ERR_XML_ERROR, "%s",
> @@ -439,10 +440,20 @@ virCPUDefParseXML(xmlNodePtr node,
>
>           def->ncells = n;
>
> +        /* 32 vs 64 bit will differ in value of upper memory bound.
> +         * On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit
> +         * machines, our bound is off_t (2^63).
> +         */
> +        if (sizeof(unsigned long) < sizeof(long long))
> +            max = 1024ull * ULONG_MAX;
> +        else
> +            max = LLONG_MAX;
> +
>           for (i = 0; i < n; i++) {
> -            char *cpus, *memory, *memAccessStr;
> +            char *cpus, *memory, *memAccessStr, *unit;
>               int ret, ncpus = 0;
>               unsigned int cur_cell;
> +            unsigned long long bytes;
>               char *tmp = NULL;
>
>               tmp = virXMLPropString(nodes[i], "id");
> @@ -496,14 +507,34 @@ virCPUDefParseXML(xmlNodePtr node,
>                   goto error;
>               }
>
> -            ret = virStrToLong_ull(memory, NULL, 10, &def->cells[cur_cell].mem);
> +            ret = virStrToLong_ull(memory, NULL, 10, &bytes);
>               if (ret == -1) {
>                   virReportError(VIR_ERR_XML_ERROR, "%s",
>                                  _("Invalid 'memory' attribute in NUMA cell"));
>                   VIR_FREE(memory);
>                   goto error;
>               }
> +
> +            unit = virXMLPropString(nodes[i], "unit");
> +            if (!unit) {
> +                if (VIR_STRDUP(unit, "KiB") < 0)
> +                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                               _("Error processing 'memory' in NUMA cell"));
> +            }
> +
> +            if (virScaleInteger(&bytes, unit, 1024, max) < 0) {
> +                virReportError(VIR_ERR_XML_ERROR, "%s",
> +                               _("Error scaling 'memory' in NUMA cell"));
> +                VIR_FREE(memory);
> +                VIR_FREE(unit);
> +                goto error;
> +            }
> +
> +            def->cells[cur_cell].mem = VIR_DIV_UP(bytes, 1024);
> +
> +            bytes = 0;
>               VIR_FREE(memory);
> +            VIR_FREE(unit);
>
>               memAccessStr = virXMLPropString(nodes[i], "memAccess");
>               if (memAccessStr) {
> @@ -703,6 +734,7 @@ virCPUDefFormatBuf(virBufferPtr buf,
>               virBufferAsprintf(buf, " id='%zu'", i);
>               virBufferAsprintf(buf, " cpus='%s'", def->cells[i].cpustr);
>               virBufferAsprintf(buf, " memory='%llu'", def->cells[i].mem);
> +            virBufferAddLit(buf, " unit='KiB'");
>               if (memAccess)
>                   virBufferAsprintf(buf, " memAccess='%s'",
>                                     virMemAccessTypeToString(memAccess));
>

Michal




More information about the libvir-list mailing list