43fe83
From d1026b0bd63883eb1d992963559ef645f634c8fa Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <d1026b0bd63883eb1d992963559ef645f634c8fa.1383922567.git.jdenemar@redhat.com>
43fe83
From: Peter Krempa <pkrempa@redhat.com>
43fe83
Date: Fri, 8 Nov 2013 12:33:34 +0100
43fe83
Subject: [PATCH] qemu: Add support for paravirtual spinlocks in the guest
43fe83
43fe83
The linux kernel recently added support for paravirtual spinlock
43fe83
handling to avoid performance regressions on overcomitted hosts. This
43fe83
feature needs to be turned in the hypervisor so that the guest OS is
43fe83
notified about the possible support.
43fe83
43fe83
This patch adds a new feature "paravirt-spinlock" to the XML and
43fe83
supporting code to enable the "kvm_pv_unhalt" pseudo CPU feature in
43fe83
qemu.
43fe83
43fe83
https://bugzilla.redhat.com/show_bug.cgi?id=1008989
43fe83
(cherry picked from commit e0dc851164d57f26ec10ceed022fe913f76ba24c)
43fe83
43fe83
    Conflicts:
43fe83
    tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args:
43fe83
    tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args:
43fe83
           commit a216e6487255d not backported
43fe83
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 docs/formatdomain.html.in                          |  8 +++++
43fe83
 docs/schemas/domaincommon.rng                      | 10 +++++-
43fe83
 src/conf/domain_conf.c                             | 36 +++++++++++++++++++++-
43fe83
 src/conf/domain_conf.h                             |  1 +
43fe83
 src/qemu/qemu_command.c                            | 13 ++++++++
43fe83
 .../qemuxml2argv-pv-spinlock-disabled.args         |  5 +++
43fe83
 .../qemuxml2argv-pv-spinlock-disabled.xml          | 26 ++++++++++++++++
43fe83
 .../qemuxml2argv-pv-spinlock-enabled.args          |  5 +++
43fe83
 .../qemuxml2argv-pv-spinlock-enabled.xml           | 26 ++++++++++++++++
43fe83
 tests/qemuxml2argvtest.c                           |  2 ++
43fe83
 tests/qemuxml2xmltest.c                            |  2 ++
43fe83
 11 files changed, 132 insertions(+), 2 deletions(-)
43fe83
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args
43fe83
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
43fe83
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args
43fe83
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
43fe83
43fe83
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
43fe83
index 132c16c..913c011 100644
43fe83
--- a/docs/formatdomain.html.in
43fe83
+++ b/docs/formatdomain.html.in
43fe83
@@ -1191,6 +1191,7 @@
43fe83
       <vapic state='on'/>
43fe83
       <spinlocks state='on' retries='4096'</spinlocks>
43fe83
     </hyperv>
43fe83
+    <pvspinlock/>
43fe83
 
43fe83
   </features>
43fe83
   ...
43fe83
@@ -1262,6 +1263,13 @@
43fe83
         
43fe83
       
43fe83
       
43fe83
+      
pvspinlock
43fe83
+      
Notify the guest that the host supports paravirtual spinlocks
43fe83
+          for example by exposing the pvticketlocks mechanism. This feature
43fe83
+          can be explicitly disabled by using state='off'
43fe83
+          attribute.
43fe83
+      
43fe83
+
43fe83
     
43fe83
 
43fe83
     

Time keeping

43fe83
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
43fe83
index 9563893..4e61d7c 100644
43fe83
--- a/docs/schemas/domaincommon.rng
43fe83
+++ b/docs/schemas/domaincommon.rng
43fe83
@@ -3510,7 +3510,7 @@
43fe83
   </define>
43fe83
   
43fe83
       A set of optional features: PAE, APIC, ACPI,
43fe83
-      HyperV Enlightenment and HAP support
43fe83
+      HyperV Enlightenment, paravirtual spinlocks  and HAP support
43fe83
     -->
43fe83
   <define name="features">
43fe83
     <optional>
43fe83
@@ -3556,6 +3556,14 @@
43fe83
               <empty/>
43fe83
             </element>
43fe83
           </optional>
43fe83
+          <optional>
43fe83
+            <element name="pvspinlock">
43fe83
+              <optional>
43fe83
+                <ref name="featurestate"/>
43fe83
+              </optional>
43fe83
+              <empty/>
43fe83
+            </element>
43fe83
+          </optional>
43fe83
         </interleave>
43fe83
       </element>
43fe83
     </optional>
43fe83
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
43fe83
index 6664c2a..57a82b6 100644
43fe83
--- a/src/conf/domain_conf.c
43fe83
+++ b/src/conf/domain_conf.c
43fe83
@@ -142,7 +142,8 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
43fe83
               "hap",
43fe83
               "viridian",
43fe83
               "privnet",
43fe83
-              "hyperv")
43fe83
+              "hyperv",
43fe83
+              "pvspinlock")
43fe83
 
43fe83
 VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST,
43fe83
               "default",
43fe83
@@ -11343,6 +11344,22 @@ virDomainDefParseXML(xmlDocPtr xml,
43fe83
             def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
             break;
43fe83
 
43fe83
+        case VIR_DOMAIN_FEATURE_PVSPINLOCK:
43fe83
+            node = ctxt->node;
43fe83
+            ctxt->node = nodes[i];
43fe83
+            if ((tmp = virXPathString("string(./@state)", ctxt))) {
43fe83
+                if ((def->features[val] = virDomainFeatureStateTypeFromString(tmp)) == -1) {
43fe83
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
43fe83
+                                   _("unknown state atribute '%s' of feature '%s'"),
43fe83
+                                   tmp, virDomainFeatureTypeToString(val));
43fe83
+                    goto error;
43fe83
+                }
43fe83
+            } else {
43fe83
+                def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
43fe83
+            }
43fe83
+            ctxt->node = node;
43fe83
+            break;
43fe83
+
43fe83
         case VIR_DOMAIN_FEATURE_LAST:
43fe83
             break;
43fe83
         }
43fe83
@@ -16706,6 +16723,23 @@ virDomainDefFormatInternal(virDomainDefPtr def,
43fe83
 
43fe83
                 break;
43fe83
 
43fe83
+            case VIR_DOMAIN_FEATURE_PVSPINLOCK:
43fe83
+                switch ((enum virDomainFeatureState) def->features[i]) {
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_LAST:
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_DEFAULT:
43fe83
+                    break;
43fe83
+
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_ON:
43fe83
+                   virBufferAsprintf(buf, "    <%s state='on'/>\n", name);
43fe83
+                   break;
43fe83
+
43fe83
+                case VIR_DOMAIN_FEATURE_STATE_OFF:
43fe83
+                   virBufferAsprintf(buf, "    <%s state='off'/>\n", name);
43fe83
+                   break;
43fe83
+                }
43fe83
+
43fe83
+                break;
43fe83
+
43fe83
             case VIR_DOMAIN_FEATURE_APIC:
43fe83
                 if (def->features[i] == VIR_DOMAIN_FEATURE_STATE_ON) {
43fe83
                     virBufferAddLit(buf, "    
43fe83
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
43fe83
index 3d2b3a4..1d27ccd 100644
43fe83
--- a/src/conf/domain_conf.h
43fe83
+++ b/src/conf/domain_conf.h
43fe83
@@ -1603,6 +1603,7 @@ enum virDomainFeature {
43fe83
     VIR_DOMAIN_FEATURE_VIRIDIAN,
43fe83
     VIR_DOMAIN_FEATURE_PRIVNET,
43fe83
     VIR_DOMAIN_FEATURE_HYPERV,
43fe83
+    VIR_DOMAIN_FEATURE_PVSPINLOCK,
43fe83
 
43fe83
     VIR_DOMAIN_FEATURE_LAST
43fe83
 };
43fe83
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
43fe83
index f14b0f2..0d08852 100644
43fe83
--- a/src/qemu/qemu_command.c
43fe83
+++ b/src/qemu/qemu_command.c
43fe83
@@ -6574,6 +6574,19 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
43fe83
         have_cpu = true;
43fe83
     }
43fe83
 
43fe83
+    if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) {
43fe83
+        char sign;
43fe83
+        if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON)
43fe83
+            sign = '+';
43fe83
+        else
43fe83
+            sign = '-';
43fe83
+
43fe83
+        virBufferAsprintf(&buf, "%s,%ckvm_pv_unhalt",
43fe83
+                          have_cpu ? "" : default_model,
43fe83
+                          sign);
43fe83
+        have_cpu = true;
43fe83
+    }
43fe83
+
43fe83
     if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
43fe83
         if (!have_cpu) {
43fe83
             virBufferAdd(&buf, default_model, -1);
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args
43fe83
new file mode 100644
43fe83
index 0000000..65c66ec
43fe83
--- /dev/null
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args
43fe83
@@ -0,0 +1,5 @@
43fe83
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
43fe83
+/usr/bin/qemu -S -M pc \
43fe83
+-cpu qemu32,-kvm_pv_unhalt -m 214 -smp 6 -nographic -monitor \
43fe83
+unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial \
43fe83
+none -parallel none
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
43fe83
new file mode 100644
43fe83
index 0000000..4820476
43fe83
--- /dev/null
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
43fe83
@@ -0,0 +1,26 @@
43fe83
+<domain type='qemu'>
43fe83
+  <name>QEMUGuest1</name>
43fe83
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
43fe83
+  <memory unit='KiB'>219100</memory>
43fe83
+  <currentMemory unit='KiB'>219100</currentMemory>
43fe83
+  <vcpu placement='static'>6</vcpu>
43fe83
+  <os>
43fe83
+    <type arch='i686' machine='pc'>hvm</type>
43fe83
+    <boot dev='network'/>
43fe83
+  </os>
43fe83
+  <features>
43fe83
+    <acpi/>
43fe83
+    <pae/>
43fe83
+    <pvspinlock state='off'/>
43fe83
+  </features>
43fe83
+  <clock offset='utc'/>
43fe83
+  <on_poweroff>destroy</on_poweroff>
43fe83
+  <on_reboot>restart</on_reboot>
43fe83
+  <on_crash>destroy</on_crash>
43fe83
+  <devices>
43fe83
+    <emulator>/usr/bin/qemu</emulator>
43fe83
+    <controller type='usb' index='0'/>
43fe83
+    <controller type='pci' index='0' model='pci-root'/>
43fe83
+    <memballoon model='virtio'/>
43fe83
+  </devices>
43fe83
+</domain>
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args
43fe83
new file mode 100644
43fe83
index 0000000..dc4cbe1
43fe83
--- /dev/null
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args
43fe83
@@ -0,0 +1,5 @@
43fe83
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
43fe83
+/usr/bin/qemu -S -M pc \
43fe83
+-cpu qemu32,+kvm_pv_unhalt -m 214 -smp 6 -nographic -monitor \
43fe83
+unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial \
43fe83
+none -parallel none
43fe83
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
43fe83
new file mode 100644
43fe83
index 0000000..ac8781b
43fe83
--- /dev/null
43fe83
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
43fe83
@@ -0,0 +1,26 @@
43fe83
+<domain type='qemu'>
43fe83
+  <name>QEMUGuest1</name>
43fe83
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
43fe83
+  <memory unit='KiB'>219100</memory>
43fe83
+  <currentMemory unit='KiB'>219100</currentMemory>
43fe83
+  <vcpu placement='static'>6</vcpu>
43fe83
+  <os>
43fe83
+    <type arch='i686' machine='pc'>hvm</type>
43fe83
+    <boot dev='network'/>
43fe83
+  </os>
43fe83
+  <features>
43fe83
+    <acpi/>
43fe83
+    <pae/>
43fe83
+    <pvspinlock state='on'/>
43fe83
+  </features>
43fe83
+  <clock offset='utc'/>
43fe83
+  <on_poweroff>destroy</on_poweroff>
43fe83
+  <on_reboot>restart</on_reboot>
43fe83
+  <on_crash>destroy</on_crash>
43fe83
+  <devices>
43fe83
+    <emulator>/usr/bin/qemu</emulator>
43fe83
+    <controller type='usb' index='0'/>
43fe83
+    <controller type='pci' index='0' model='pci-root'/>
43fe83
+    <memballoon model='virtio'/>
43fe83
+  </devices>
43fe83
+</domain>
43fe83
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
43fe83
index 1d964ce..2f05727 100644
43fe83
--- a/tests/qemuxml2argvtest.c
43fe83
+++ b/tests/qemuxml2argvtest.c
43fe83
@@ -446,6 +446,8 @@ mymain(void)
43fe83
             QEMU_CAPS_CHARDEV_SPICEVMC, QEMU_CAPS_SPICE, QEMU_CAPS_HDA_DUPLEX);
43fe83
     DO_TEST("eoi-disabled", NONE);
43fe83
     DO_TEST("eoi-enabled", NONE);
43fe83
+    DO_TEST("pv-spinlock-disabled", NONE);
43fe83
+    DO_TEST("pv-spinlock-enabled", NONE);
43fe83
     DO_TEST("kvmclock+eoi-disabled", QEMU_CAPS_ENABLE_KVM);
43fe83
 
43fe83
     DO_TEST("hyperv", NONE);
43fe83
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
43fe83
index 6eebc68..5a47ef8 100644
43fe83
--- a/tests/qemuxml2xmltest.c
43fe83
+++ b/tests/qemuxml2xmltest.c
43fe83
@@ -156,6 +156,8 @@ mymain(void)
43fe83
     DO_TEST("cpu-eoi-enabled");
43fe83
     DO_TEST("eoi-disabled");
43fe83
     DO_TEST("eoi-enabled");
43fe83
+    DO_TEST("pv-spinlock-disabled");
43fe83
+    DO_TEST("pv-spinlock-enabled");
43fe83
 
43fe83
     DO_TEST("hyperv");
43fe83
     DO_TEST("hyperv-off");
43fe83
-- 
43fe83
1.8.4.2
43fe83