qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC 2/2] qmp: Implement cpu-add in terms of query-hotplugg


From: David Gibson
Subject: [Qemu-devel] [RFC 2/2] qmp: Implement cpu-add in terms of query-hotpluggable-cpus when available
Date: Mon, 18 Jul 2016 19:19:20 +1000

We've recently added a new device_add based cpu hotplug
implementation, with the spapr machine type being the first user.  In
order to overcome the limitations of the old cpu_add interface, it
works very differently.  That's going to require a new interface in
libvirt to properly use the new interface in qemu, which will in turn
require work further up the stack to make use of it.

While that's certainly necessary in the long run, it would be nice if
we could have at least something working with the old cpu_add
interface.  This patch is an attempt to do so.

This patch implements cpu-add on machines which don't support it
directly but which do support the query-hotpluggable-cpus interface.
Essentially,
        cpu-add <n>
will be treated as a device_add of the n-th entry in the list provided
by query-hotpluggable-cpus.

This means that on spapr cpu-add will add a whole core, not a single
vcpu as on x86. That's arguably cheating on the cpu-add semantics, but
AFAICT those were never terribly well defined anyway.
---
 qmp.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/qmp.c b/qmp.c
index b6d531e..cde02c4 100644
--- a/qmp.c
+++ b/qmp.c
@@ -17,6 +17,7 @@
 #include "qemu-version.h"
 #include "qemu/cutils.h"
 #include "monitor/monitor.h"
+#include "monitor/qdev.h"
 #include "sysemu/sysemu.h"
 #include "qmp-commands.h"
 #include "sysemu/char.h"
@@ -29,6 +30,7 @@
 #include "sysemu/block-backend.h"
 #include "qom/qom-qobject.h"
 #include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp-input-visitor.h"
 #include "hw/boards.h"
@@ -133,6 +135,65 @@ void qmp_cpu(int64_t index, Error **errp)
     /* Just do nothing */
 }
 
+static void qmp_compat_cpu_add(int64_t id, Error **errp)
+{
+    Error *err = NULL;
+    MachineClass *mc = MACHINE_GET_CLASS(current_machine);
+    HotpluggableCPUList *l = mc->query_hotpluggable_cpus(current_machine);
+    HotpluggableCPUList *list_item;
+    HotpluggableCPU *cpu_item;
+    QDict *opts = NULL;
+    int64_t i;
+
+    if (!l) {
+        goto out;
+    }
+
+    for (list_item = l, i = 0;
+         list_item;
+         list_item = list_item->next, i++) {
+        if (i == id) {
+            break;
+        }
+    }
+
+    if (!list_item) {
+        error_setg(errp, "CPU id must be in the range 0..%" PRId64,
+                   i - 1);
+        goto out;
+    }
+
+    cpu_item = list_item->value;
+
+    opts = qdict_new();
+    qdict_put(opts, "driver", qstring_from_str(cpu_item->type));
+    if (cpu_item->props->has_node_id) {
+        qdict_put(opts, "node-id", qint_from_int(cpu_item->props->node_id));
+    }
+    if (cpu_item->props->has_socket_id) {
+        qdict_put(opts, "socket-id", 
qint_from_int(cpu_item->props->socket_id));
+    }
+    if (cpu_item->props->has_core_id) {
+        qdict_put(opts, "core-id", qint_from_int(cpu_item->props->core_id));
+    }
+    if (cpu_item->props->has_thread_id) {
+        qdict_put(opts, "thread-id", 
qint_from_int(cpu_item->props->thread_id));
+    }
+
+    qmp_device_add(opts, NULL, &err);
+    if (err) {
+        error_propagate(errp, err);
+    }
+
+out:
+    if (opts) {
+        QDECREF(opts);
+    }
+    if (l) {
+        qapi_free_HotpluggableCPUList(l);
+    }
+}
+
 void qmp_cpu_add(int64_t id, Error **errp)
 {
     MachineClass *mc;
@@ -140,6 +201,8 @@ void qmp_cpu_add(int64_t id, Error **errp)
     mc = MACHINE_GET_CLASS(current_machine);
     if (mc->hot_add_cpu) {
         mc->hot_add_cpu(id, errp);
+    } else if (mc->query_hotpluggable_cpus) {
+        qmp_compat_cpu_add(id, errp);
     } else {
         error_setg(errp, "Not supported");
     }
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]