CPU related capabilities may differ depending on accelerator used
when
probing. Let's use KVM if available and fall back to TCG.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
Notes:
Or should we perhaps start probing QEMU in both TCG and KVM
mode since some capabilities may actually differ depending on
the accelerator? Probing QEMU twice for both TCG and KVM would
be cleaner and we could real capabilities for both QEMU and KVM
domain types. And the two ugly patches at the end of this series
would not be needed anymore. However running QEMU twice was
always considered harmful, which is why I came up with this a bit
ugly solution.
As we've discussed this outside of mailing list, QEMU is planing to rewrite the
way how they initialize itself and we will be able to probe TCG and KVM
differences no matter what accel was used to start the QEMU process. This means
that we will have to store the difference somehow for both TCG and KVM.
As you've mentioned it would be cleaner solution to have both capabilities
available so I would say that we should go for it. To reduce the impact of
probing twice (until QEMU rewrites the probing) we can probe only once for
the best capabilities (KVM if available otherwise for TCG) and probe for the
second one only when it is explicitly required by some guest. In most cases
during libvirtd lifetime there are only KVM or TCG guests.
Note: adding Dan to CC for his opinion.
Pavel
src/qemu/qemu_capabilities.c | 10 ++-
src/qemu/qemu_capspriv.h | 2 +
tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml | 16 ++--
.../qemucapabilitiesdata/caps_2.8.0.x86_64.replies | 87 +++-------------------
tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 20 ++---
tests/qemucapsprobe.c | 15 +++-
6 files changed, 53 insertions(+), 97 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2df710a..b9e94dc 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3869,6 +3869,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
pid_t pid = 0;
virDomainObjPtr vm = NULL;
virDomainXMLOptionPtr xmlopt = NULL;
+ const char *machine;
/* the ".sock" sufix is important to avoid a possible clash with a qemu
* domain called "capabilities"
@@ -3896,6 +3897,13 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
VIR_DEBUG("Try to get caps via QMP qemuCaps=%p", qemuCaps);
+ if (flags & VIR_QEMU_CAPS_NEW_FORCE_KVM)
+ machine = "none,accel=kvm";
+ else if (flags & VIR_QEMU_CAPS_NEW_FORCE_TCG)
+ machine = "none,accel=tcg";
+ else
+ machine = "none,accel=kvm:tcg";
+
/*
* We explicitly need to use -daemonize here, rather than
* virCommandDaemonize, because we need to synchronize
@@ -3908,7 +3916,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
"-no-user-config",
"-nodefaults",
"-nographic",
- "-M", "none",
+ "-machine", machine,
"-qmp", monarg,
"-pidfile", pidfile,
"-daemonize",
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 573cba6..68b2d82 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -41,6 +41,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps);
typedef enum {
VIR_QEMU_CAPS_NEW_FORCE_QMP = 1 << 0,
+ VIR_QEMU_CAPS_NEW_FORCE_TCG = 1 << 1,
+ VIR_QEMU_CAPS_NEW_FORCE_KVM = 1 << 2,
} virQEMUCapsNewFlags;
virQEMUCapsPtr
diff --git a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
b/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
index 3acb29f..4c5fffc 100644
--- a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml
@@ -35,10 +35,10 @@
<model usable='yes'>kvm32</model>
<model usable='yes'>coreduo</model>
<model usable='yes'>core2duo</model>
- <model usable='yes'>athlon</model>
+ <model usable='no'>athlon</model>
<model usable='yes'>Westmere</model>
- <model usable='no'>Skylake-Client</model>
- <model usable='no'>SandyBridge</model>
+ <model usable='yes'>Skylake-Client</model>
+ <model usable='yes'>SandyBridge</model>
<model usable='yes'>Penryn</model>
<model usable='no'>Opteron_G5</model>
<model usable='no'>Opteron_G4</model>
@@ -46,12 +46,12 @@
<model usable='yes'>Opteron_G2</model>
<model usable='yes'>Opteron_G1</model>
<model usable='yes'>Nehalem</model>
- <model usable='no'>IvyBridge</model>
- <model usable='no'>Haswell</model>
- <model usable='no'>Haswell-noTSX</model>
+ <model usable='yes'>IvyBridge</model>
+ <model usable='yes'>Haswell</model>
+ <model usable='yes'>Haswell-noTSX</model>
<model usable='yes'>Conroe</model>
- <model usable='no'>Broadwell</model>
- <model usable='no'>Broadwell-noTSX</model>
+ <model usable='yes'>Broadwell</model>
+ <model usable='yes'>Broadwell-noTSX</model>
<model usable='yes'>486</model>
</mode>
</cpu>
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.replies
b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.replies
index d32e8b3..296e0ed 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.replies
@@ -466,7 +466,7 @@
{
"return": {
- "fd": 14,
+ "fd": 16,
"fdset-id": 0
},
"id": "libvirt-5"
@@ -3799,7 +3799,6 @@
{
"name": "host",
"unavailable-features": [
- "kvm"
],
"static": false
},
@@ -3818,7 +3817,11 @@
{
"name": "phenom",
"unavailable-features": [
+ "mmxext",
"fxsr-opt",
+ "3dnowext",
+ "3dnow",
+ "sse4a",
"npt"
],
"static": false
@@ -3874,6 +3877,9 @@
{
"name": "athlon",
"unavailable-features": [
+ "mmxext",
+ "3dnowext",
+ "3dnow"
],
"static": false
},
@@ -3886,29 +3892,12 @@
{
"name": "Skylake-Client",
"unavailable-features": [
- "fma",
- "pcid",
- "x2apic",
- "tsc-deadline",
- "avx",
- "f16c",
- "rdrand",
- "hle",
- "avx2",
- "invpcid",
- "rtm",
- "rdseed",
- "3dnowprefetch",
- "xsavec"
],
"static": false
},
{
"name": "SandyBridge",
"unavailable-features": [
- "x2apic",
- "tsc-deadline",
- "avx"
],
"static": false
},
@@ -3921,11 +3910,8 @@
{
"name": "Opteron_G5",
"unavailable-features": [
- "fma",
- "avx",
- "f16c",
+ "sse4a",
"misalignsse",
- "3dnowprefetch",
"xop",
"fma4",
"tbm"
@@ -3935,9 +3921,8 @@
{
"name": "Opteron_G4",
"unavailable-features": [
- "avx",
+ "sse4a",
"misalignsse",
- "3dnowprefetch",
"xop",
"fma4"
],
@@ -3946,6 +3931,7 @@
{
"name": "Opteron_G3",
"unavailable-features": [
+ "sse4a",
"misalignsse"
],
"static": false
@@ -3971,43 +3957,18 @@
{
"name": "IvyBridge",
"unavailable-features": [
- "x2apic",
- "tsc-deadline",
- "avx",
- "f16c",
- "rdrand"
],
"static": false
},
{
"name": "Haswell",
"unavailable-features": [
- "fma",
- "pcid",
- "x2apic",
- "tsc-deadline",
- "avx",
- "f16c",
- "rdrand",
- "hle",
- "avx2",
- "invpcid",
- "rtm"
],
"static": false
},
{
"name": "Haswell-noTSX",
"unavailable-features": [
- "fma",
- "pcid",
- "x2apic",
- "tsc-deadline",
- "avx",
- "f16c",
- "rdrand",
- "avx2",
- "invpcid"
],
"static": false
},
@@ -4020,36 +3981,12 @@
{
"name": "Broadwell",
"unavailable-features": [
- "fma",
- "pcid",
- "x2apic",
- "tsc-deadline",
- "avx",
- "f16c",
- "rdrand",
- "hle",
- "avx2",
- "invpcid",
- "rtm",
- "rdseed",
- "3dnowprefetch"
],
"static": false
},
{
"name": "Broadwell-noTSX",
"unavailable-features": [
- "fma",
- "pcid",
- "x2apic",
- "tsc-deadline",
- "avx",
- "f16c",
- "rdrand",
- "avx2",
- "invpcid",
- "rdseed",
- "3dnowprefetch"
],
"static": false
},
@@ -4065,7 +4002,7 @@
{
"return": {
- "enabled": false,
+ "enabled": true,
"present": true
},
"id": "libvirt-42"
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
index 117b2b0..feb4cfa 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
@@ -3,10 +3,10 @@
<selfctime>0</selfctime>
<selfvers>0</selfvers>
<usedQMP/>
+ <flag name='kvm'/>
<flag name='mem-path'/>
<flag name='drive-serial'/>
<flag name='chardev'/>
- <flag name='enable-kvm'/>
<flag name='monitor-json'/>
<flag name='sdl'/>
<flag name='netdev'/>
@@ -196,7 +196,7 @@
<kvmVersion>0</kvmVersion>
<package> (v2.7.0-1292-g45b567d-dirty)</package>
<arch>x86_64</arch>
- <cpu name='host' usable='no'/>
+ <cpu name='host' usable='yes'/>
<cpu name='qemu64' usable='yes'/>
<cpu name='qemu32' usable='yes'/>
<cpu name='phenom' usable='no'/>
@@ -208,10 +208,10 @@
<cpu name='kvm32' usable='yes'/>
<cpu name='coreduo' usable='yes'/>
<cpu name='core2duo' usable='yes'/>
- <cpu name='athlon' usable='yes'/>
+ <cpu name='athlon' usable='no'/>
<cpu name='Westmere' usable='yes'/>
- <cpu name='Skylake-Client' usable='no'/>
- <cpu name='SandyBridge' usable='no'/>
+ <cpu name='Skylake-Client' usable='yes'/>
+ <cpu name='SandyBridge' usable='yes'/>
<cpu name='Penryn' usable='yes'/>
<cpu name='Opteron_G5' usable='no'/>
<cpu name='Opteron_G4' usable='no'/>
@@ -219,12 +219,12 @@
<cpu name='Opteron_G2' usable='yes'/>
<cpu name='Opteron_G1' usable='yes'/>
<cpu name='Nehalem' usable='yes'/>
- <cpu name='IvyBridge' usable='no'/>
- <cpu name='Haswell' usable='no'/>
- <cpu name='Haswell-noTSX' usable='no'/>
+ <cpu name='IvyBridge' usable='yes'/>
+ <cpu name='Haswell' usable='yes'/>
+ <cpu name='Haswell-noTSX' usable='yes'/>
<cpu name='Conroe' usable='yes'/>
- <cpu name='Broadwell' usable='no'/>
- <cpu name='Broadwell-noTSX' usable='no'/>
+ <cpu name='Broadwell' usable='yes'/>
+ <cpu name='Broadwell-noTSX' usable='yes'/>
<cpu name='486' usable='yes'/>
<machine name='pc-i440fx-2.8' alias='pc' hotplugCpus='yes'
maxCpus='255'/>
<machine name='pc-0.12' hotplugCpus='yes'
maxCpus='255'/>
diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
index 0f59bb9..63fa499 100644
--- a/tests/qemucapsprobe.c
+++ b/tests/qemucapsprobe.c
@@ -51,8 +51,17 @@ main(int argc, char **argv)
VIRT_TEST_PRELOAD(abs_builddir "/.libs/qemucapsprobemock.so");
- if (argc != 2) {
- fprintf(stderr, "%s QEMU_binary\n", argv[0]);
+ if (argc != 3) {
+ fprintf(stderr, "%s kvm|tcg QEMU_binary\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (STREQ(argv[1], "tcg")) {
+ flags |= VIR_QEMU_CAPS_NEW_FORCE_TCG;
+ } else if (STREQ(argv[1], "kvm")) {
+ flags |= VIR_QEMU_CAPS_NEW_FORCE_KVM;
+ } else {
+ fprintf(stderr, "Invalid accelerator (kvm|tcg): '%s'\n",
argv[1]);
return EXIT_FAILURE;
}
@@ -71,7 +80,7 @@ main(int argc, char **argv)
if (virThreadCreate(&thread, false, eventLoop, NULL) < 0)
return EXIT_FAILURE;
- if (!(caps = virQEMUCapsNewForBinaryInternal(NULL, argv[1], "/tmp", NULL,
+ if (!(caps = virQEMUCapsNewForBinaryInternal(NULL, argv[2], "/tmp", NULL,
-1, -1, flags)))
return EXIT_FAILURE;
--
2.10.2
--
libvir-list mailing list
libvir-list(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list