On Wed, Aug 24, 2016 at 09:35:37AM -0400, Peter Krempa wrote:
Add support for using the new approach to hotplug vcpus using device_add during startup of qemu to allow sparse vcpu topologies.There are a few limitations imposed by qemu on the supported configuration: - vcpu0 needs to be always present and not hotpluggable - non-hotpluggable cpus need to be ordered at the beginning - order of the vcpus needs to be unique for every single hotpluggable entity Qemu also doesn't really allow to query the information necessary to start a VM with the vcpus directly on the commandline. Fortunately they can be hotplugged during startup. The new hotplug code uses the following approach: - non-hotpluggable vcpus are counted and put to the -smp option - qemu is started - qemu is queried for the necessary information - the configuration is checked - the hotpluggable vcpus are hotplugged - vcpus are started This patch adds a lot of checking code and enables the support to specify the individual vcpu element with qemu. --- Notes: v3: - fixed qsort comparison function (added dereference of one level) v3: - added docs to the HTML stating qemu restrictions. docs/formatdomain.html.in | 5 + src/qemu/qemu_command.c | 20 ++- src/qemu/qemu_domain.c | 76 ++++++++- src/qemu/qemu_process.c | 178 +++++++++++++++++++++ .../qemuxml2argv-cpu-hotplug-startup.args | 20 +++ .../qemuxml2argv-cpu-hotplug-startup.xml | 29 ++++ tests/qemuxml2argvtest.c | 2 + 7 files changed, 325 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-hotplug-startup.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-hotplug-startup.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 062045b..8d3168a 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -580,6 +580,11 @@ Note that providing state for individual cpus may be necessary to enable support of addressable vCPU hotplug and this feature may not be supported by all hypervisors. + + For QEMU the following conditions are required. Vcpu 0 needs to be + enabled and non-hotpluggable. On PPC64 along with it vcpus that are in + the same core need to be enabled as well. All non hotpluggable cpus
non-hotpluggable?
+ present at boot need to be grouped after vcpu 0.
<span class="since">Since 2.2.0 (QEMU only)</span>
</dd>
</dl>
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 28e5a7e..c1dc390 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7082,17 +7082,29 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
static int
qemuBuildSmpCommandLine(virCommandPtr cmd,
- const virDomainDef *def)
+ virDomainDefPtr def)
{
char *smp;
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ unsigned int maxvcpus = virDomainDefGetVcpusMax(def);
+ unsigned int nvcpus = 0;
+ virDomainVcpuDefPtr vcpu;
+ size_t i;
+
+ /* count un-hotpluggable enabled vcpus. Hotpluggable ones will be added
non-hotpluggable?
+ * in a different way */
+ for (i = 0; i < maxvcpus; i++) {
+ vcpu = virDomainDefGetVcpu(def, i);
+ if (vcpu->online && vcpu->hotpluggable == VIR_TRISTATE_BOOL_NO)
+ nvcpus++;
+ }
virCommandAddArg(cmd, "-smp");
- virBufferAsprintf(&buf, "%u", virDomainDefGetVcpus(def));
+ virBufferAsprintf(&buf, "%u", nvcpus);
- if (virDomainDefHasVcpusOffline(def))
- virBufferAsprintf(&buf, ",maxcpus=%u", virDomainDefGetVcpusMax(def));
+ if (nvcpus != maxvcpus)
+ virBufferAsprintf(&buf, ",maxcpus=%u", maxvcpus);
/* sockets, cores, and threads are either all zero
* or all non-zero, thus checking one of them is enough */
if (def->cpu && def->cpu->sockets) {
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index aa93498..970c34a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2253,6 +2253,76 @@ qemuDomainRecheckInternalPaths(virDomainDefPtr def,
static int
+qemuDomainDefVcpusPostParse(virDomainDefPtr def)
+{
+ unsigned int maxvcpus = virDomainDefGetVcpusMax(def);
+ virDomainVcpuDefPtr vcpu;
+ virDomainVcpuDefPtr prevvcpu;
+ size_t i;
+ bool has_order = false;
+
+ /* vcpu 0 needs to be present, first, and non-hotpluggable */
+ vcpu = virDomainDefGetVcpu(def, 0);
+ if (!vcpu->online) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vcpu 0 can't be offline"));
+ return -1;
+ }
+ if (vcpu->hotpluggable == VIR_TRISTATE_BOOL_YES) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vcpu0 can't be hotpluggable"));
+ return -1;
+ }
+ if (vcpu->order != 0 && vcpu->order != 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vcpu0 must be enabled first"));
+ return -1;
+ }
+
+ if (vcpu->order != 0)
+ has_order = true;
+
+ prevvcpu = vcpu;
+
+ /* all online vcpus or non online vcpu need to have order set */
+ for (i = 1; i < maxvcpus; i++) {
+ vcpu = virDomainDefGetVcpu(def, i);
+
+ if (vcpu->online &&
+ (vcpu->order != 0) != has_order) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("all vcpus must have either set or unset order"));
+ return -1;
+ }
+
+ /* few conditions for non-hotpluggable (thus online) vcpus */
+ if (vcpu->hotpluggable == VIR_TRISTATE_BOOL_NO) {
+ /* they can be ordered only at the beinning */
beginning ACK Jan
signature.asc
Description: Digital signature
-- libvir-list mailing list [email protected] https://www.redhat.com/mailman/listinfo/libvir-list
