[libvirt] [RFC PATCH 5/6] conf: Parse and format HPT maxpagesize

Andrea Bolognani posted 6 patches 7 years, 8 months ago
[libvirt] [RFC PATCH 5/6] conf: Parse and format HPT maxpagesize
Posted by Andrea Bolognani 7 years, 8 months ago
This commit is best viewed with 'git show -w'.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
 docs/schemas/domaincommon.rng                 | 21 ++++++---
 src/conf/domain_conf.c                        | 44 ++++++++++++++++---
 src/conf/domain_conf.h                        |  1 +
 tests/qemuxml2argvdata/pseries-features.xml   |  4 +-
 tests/qemuxml2argvtest.c                      |  1 +
 tests/qemuxml2xmloutdata/pseries-features.xml |  4 +-
 tests/qemuxml2xmltest.c                       |  1 +
 7 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f16e157397..7b631f7d93 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5018,13 +5018,20 @@
 
   <define name="hpt">
     <element name="hpt">
-      <attribute name="resizing">
-        <choice>
-          <value>enabled</value>
-          <value>disabled</value>
-          <value>required</value>
-        </choice>
-      </attribute>
+      <optional>
+        <attribute name="resizing">
+          <choice>
+            <value>enabled</value>
+            <value>disabled</value>
+            <value>required</value>
+          </choice>
+        </attribute>
+      </optional>
+      <optional>
+        <element name="maxpagesize">
+          <ref name='scaledInteger'/>
+        </element>
+      </optional>
     </element>
   </define>
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 20b845f02a..e84cfb0d05 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19493,8 +19493,24 @@ virDomainDefParseXML(xmlDocPtr xml,
                 VIR_FREE(tmp);
             }
 
-            if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE)
+            if (virDomainParseScaledValue("./features/hpt/maxpagesize",
+                                          NULL,
+                                          ctxt,
+                                          &def->hpt_maxpagesize,
+                                          1024,
+                                          ULLONG_MAX,
+                                          false) < 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               "%s",
+                               _("Unable to parse HPT maxpagesize setting"));
+                goto error;
+            }
+            def->hpt_maxpagesize = VIR_ROUND_UP(def->hpt_maxpagesize, 1024);
+
+            if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE ||
+                def->hpt_maxpagesize > 0) {
                 def->features[val] = VIR_TRISTATE_SWITCH_ON;
+            }
             break;
 
         /* coverity[dead_error_begin] */
@@ -21625,15 +21641,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
 
         case VIR_DOMAIN_FEATURE_HPT:
             if (src->features[i] != dst->features[i] ||
-                src->hpt_resizing != dst->hpt_resizing) {
+                src->hpt_resizing != dst->hpt_resizing ||
+                src->hpt_maxpagesize != dst->hpt_maxpagesize) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                _("State of feature '%s' differs: "
-                                 "source: '%s,%s=%s', destination: '%s,%s=%s'"),
+                                 "source: '%s,%s=%s,%s=%llu', destination: '%s,%s=%s,%s=%llu'"),
                                featureName,
                                virTristateSwitchTypeToString(src->features[i]),
                                "resizing", virDomainHPTResizingTypeToString(src->hpt_resizing),
+                               "maxpagesize", src->hpt_maxpagesize,
                                virTristateSwitchTypeToString(dst->features[i]),
-                               "resizing", virDomainHPTResizingTypeToString(dst->hpt_resizing));
+                               "resizing", virDomainHPTResizingTypeToString(dst->hpt_resizing),
+                               "maxpagesize", dst->hpt_maxpagesize);
                 return false;
             }
             break;
@@ -27209,10 +27228,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
 
             case VIR_DOMAIN_FEATURE_HPT: {
                 bool hasResizing = def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE;
+                bool hasMaxPageSize = def->hpt_maxpagesize > 0;
                 char *resizing = NULL;
 
                 if (def->features[i] != VIR_TRISTATE_SWITCH_ON ||
-                    !hasResizing) {
+                    (!hasResizing && !hasMaxPageSize)) {
                     break;
                 }
 
@@ -27226,8 +27246,18 @@ virDomainDefFormatInternal(virDomainDefPtr def,
                         goto error;
                 }
 
-                virBufferAsprintf(buf, "<hpt%s/>\n",
-                                  resizing);
+                if (hasMaxPageSize) {
+                    virBufferAsprintf(buf, "<hpt%s>\n",
+                                      resizing);
+                    virBufferAdjustIndent(buf, 2);
+                    virBufferAsprintf(buf, "<maxpagesize unit='KiB'>%llu</maxpagesize>\n",
+                                      def->hpt_maxpagesize / 1024);
+                    virBufferAdjustIndent(buf, -2);
+                    virBufferAddLit(buf, "</hpt>\n");
+                } else {
+                    virBufferAsprintf(buf, "<hpt%s/>\n",
+                                      resizing);
+                }
 
                 VIR_FREE(resizing);
                 break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cb0945b6c0..dbc649347c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2377,6 +2377,7 @@ struct _virDomainDef {
     unsigned int hyperv_spinlocks;
     virGICVersion gic_version;
     virDomainHPTResizing hpt_resizing;
+    unsigned long long hpt_maxpagesize;
     char *hyperv_vendor_id;
     int apic_eoi;
 
diff --git a/tests/qemuxml2argvdata/pseries-features.xml b/tests/qemuxml2argvdata/pseries-features.xml
index 5ef1a744c8..30cee5b81c 100644
--- a/tests/qemuxml2argvdata/pseries-features.xml
+++ b/tests/qemuxml2argvdata/pseries-features.xml
@@ -7,7 +7,9 @@
     <type arch='ppc64' machine='pseries'>hvm</type>
   </os>
   <features>
-    <hpt resizing='required'/>
+    <hpt resizing='required'>
+      <maxpagesize unit='GiB'>1</maxpagesize>
+    </hpt>
   </features>
   <devices>
     <emulator>/usr/bin/qemu-system-ppc64</emulator>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 1d023129ac..a7392ea655 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1822,6 +1822,7 @@ mymain(void)
 
     DO_TEST("pseries-features",
             QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+            QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MPS,
             QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
     DO_TEST_FAILURE("pseries-features",
                     QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE);
diff --git a/tests/qemuxml2xmloutdata/pseries-features.xml b/tests/qemuxml2xmloutdata/pseries-features.xml
index e8ed842fb6..f36705f011 100644
--- a/tests/qemuxml2xmloutdata/pseries-features.xml
+++ b/tests/qemuxml2xmloutdata/pseries-features.xml
@@ -9,7 +9,9 @@
     <boot dev='hd'/>
   </os>
   <features>
-    <hpt resizing='required'/>
+    <hpt resizing='required'>
+      <maxpagesize unit='KiB'>1048576</maxpagesize>
+    </hpt>
   </features>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index e31d8212fe..128c14d5d1 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -617,6 +617,7 @@ mymain(void)
 
     DO_TEST("pseries-features",
             QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+            QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MPS,
             QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     DO_TEST("pseries-serial-native",
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 5/6] conf: Parse and format HPT maxpagesize
Posted by Peter Krempa 7 years, 8 months ago
On Wed, May 23, 2018 at 18:18:01 +0200, Andrea Bolognani wrote:
> This commit is best viewed with 'git show -w'.
> 
> Signed-off-by: Andrea Bolognani <abologna@redhat.com>
> ---
>  docs/schemas/domaincommon.rng                 | 21 ++++++---
>  src/conf/domain_conf.c                        | 44 ++++++++++++++++---
>  src/conf/domain_conf.h                        |  1 +
>  tests/qemuxml2argvdata/pseries-features.xml   |  4 +-
>  tests/qemuxml2argvtest.c                      |  1 +
>  tests/qemuxml2xmloutdata/pseries-features.xml |  4 +-
>  tests/qemuxml2xmltest.c                       |  1 +
>  7 files changed, 60 insertions(+), 16 deletions(-)
> 

[...]

> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 20b845f02a..e84cfb0d05 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -19493,8 +19493,24 @@ virDomainDefParseXML(xmlDocPtr xml,
>                  VIR_FREE(tmp);
>              }
>  
> -            if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE)
> +            if (virDomainParseScaledValue("./features/hpt/maxpagesize",
> +                                          NULL,
> +                                          ctxt,
> +                                          &def->hpt_maxpagesize,
> +                                          1024,
> +                                          ULLONG_MAX,
> +                                          false) < 0) {
> +                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                               "%s",
> +                               _("Unable to parse HPT maxpagesize setting"));
> +                goto error;
> +            }
> +            def->hpt_maxpagesize = VIR_ROUND_UP(def->hpt_maxpagesize, 1024);

The code in the patch using it with qemu actually expects so this is a
power of 2, so you'll need a different rounding function. 
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 5/6] conf: Parse and format HPT maxpagesize
Posted by Andrea Bolognani 7 years, 8 months ago
On Wed, 2018-05-23 at 18:36 +0200, Peter Krempa wrote:
> On Wed, May 23, 2018 at 18:18:01 +0200, Andrea Bolognani wrote:
> > +            def->hpt_maxpagesize = VIR_ROUND_UP(def->hpt_maxpagesize, 1024);
> 
> The code in the patch using it with qemu actually expects so this is a
> power of 2, so you'll need a different rounding function. 

Good point!

Looks like VIR_ROUND_UP_POWER_OF_TWO() will do the trick.

-- 
Andrea Bolognani / Red Hat / Virtualization

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 5/6] conf: Parse and format HPT maxpagesize
Posted by Peter Krempa 7 years, 8 months ago
On Wed, May 23, 2018 at 18:52:57 +0200, Andrea Bolognani wrote:
> On Wed, 2018-05-23 at 18:36 +0200, Peter Krempa wrote:
> > On Wed, May 23, 2018 at 18:18:01 +0200, Andrea Bolognani wrote:
> > > +            def->hpt_maxpagesize = VIR_ROUND_UP(def->hpt_maxpagesize, 1024);
> > 
> > The code in the patch using it with qemu actually expects so this is a
> > power of 2, so you'll need a different rounding function. 
> 
> Good point!
> 
> Looks like VIR_ROUND_UP_POWER_OF_TWO() will do the trick.

Yes. We usually do the rounding in the code which prepares the
definition for the startup of the VM though, so that other hypervisor
drivers don't need to share the limits of qemu.

Given that this is a ppc64 specific option it probably does not matter
much.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list