summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell2017-04-21 16:59:27 +0200
committerPeter Maydell2017-04-21 16:59:27 +0200
commit32c7e0ab755745e961f1772e95cac381cc68769d (patch)
treefa40ac2dd8de6e9d4dfa6607c41cc7ee03c3daf7 /hw
parentMerge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' int... (diff)
parenthmp: info migrate_parameters format tunes (diff)
downloadqemu-32c7e0ab755745e961f1772e95cac381cc68769d.tar.gz
qemu-32c7e0ab755745e961f1772e95cac381cc68769d.tar.xz
qemu-32c7e0ab755745e961f1772e95cac381cc68769d.zip
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging
migration/next for 20170421 # gpg: Signature made Fri 21 Apr 2017 11:28:13 BST # gpg: using RSA key 0xF487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" # gpg: aka "Juan Quintela <quintela@trasno.org>" # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * remotes/juanquintela/tags/migration/20170421: (65 commits) hmp: info migrate_parameters format tunes hmp: info migrate_capability format tunes migration: rename max_size to threshold_size migration: set current_active_state once virtio-rng: stop virtqueue while the CPU is stopped migration: don't close a file descriptor while it can be in use ram: Remove migration_bitmap_extend() migration: Disable hotplug/unplug during migration qdev: Move qdev_unplug() to qdev-monitor.c qdev: Export qdev_hot_removed qdev: qdev_hotplug is really a bool migration: Remove MigrationState parameter from migration_is_idle() ram: Use RAMBitmap type for coherence ram: rename last_ram_offset() last_ram_pages() ram: Use ramblock and page offset instead of absolute offset ram: Change offset field in PageSearchStatus to page ram: Remember last_page instead of last_offset ram: Use page number instead of an address for the bitmap operations ram: reorganize last_sent_block ram: ram_discard_range() don't use the mis parameter ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/core/qdev.c40
-rw-r--r--hw/virtio/trace-events3
-rw-r--r--hw/virtio/virtio-rng.c29
3 files changed, 29 insertions, 43 deletions
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 695d7c4216..02b632f6b3 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -39,9 +39,9 @@
#include "qapi-event.h"
#include "migration/migration.h"
-int qdev_hotplug = 0;
+bool qdev_hotplug = false;
static bool qdev_hot_added = false;
-static bool qdev_hot_removed = false;
+bool qdev_hot_removed = false;
const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
{
@@ -271,40 +271,6 @@ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
return hotplug_ctrl;
}
-void qdev_unplug(DeviceState *dev, Error **errp)
-{
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
- HotplugHandler *hotplug_ctrl;
- HotplugHandlerClass *hdc;
-
- if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
- error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
- return;
- }
-
- if (!dc->hotpluggable) {
- error_setg(errp, QERR_DEVICE_NO_HOTPLUG,
- object_get_typename(OBJECT(dev)));
- return;
- }
-
- qdev_hot_removed = true;
-
- hotplug_ctrl = qdev_get_hotplug_handler(dev);
- /* hotpluggable device MUST have HotplugHandler, if it doesn't
- * then something is very wrong with it */
- g_assert(hotplug_ctrl);
-
- /* If device supports async unplug just request it to be done,
- * otherwise just remove it synchronously */
- hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
- if (hdc->unplug_request) {
- hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
- } else {
- hotplug_handler_unplug(hotplug_ctrl, dev, errp);
- }
-}
-
static int qdev_reset_one(DeviceState *dev, void *opaque)
{
device_reset(dev);
@@ -385,7 +351,7 @@ void qdev_machine_creation_done(void)
* ok, initial machine setup is done, starting from now we can
* only create hotpluggable devices
*/
- qdev_hotplug = 1;
+ qdev_hotplug = true;
}
bool qdev_machine_modified(void)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 6926eedd3f..1f7a7c1ae1 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -11,8 +11,11 @@ virtio_set_status(void *vdev, uint8_t val) "vdev %p val %u"
# hw/virtio/virtio-rng.c
virtio_rng_guest_not_ready(void *rng) "rng %p: guest not ready"
+virtio_rng_cpu_is_stopped(void *rng, int size) "rng %p: cpu is stopped, dropping %d bytes"
+virtio_rng_popped(void *rng) "rng %p: elem popped"
virtio_rng_pushed(void *rng, size_t len) "rng %p: %zd bytes pushed"
virtio_rng_request(void *rng, size_t size, unsigned quota) "rng %p: %zd bytes requested, %u bytes quota left"
+virtio_rng_vm_state_change(void *rng, int running, int state) "rng %p: state change to running %d state %d"
# hw/virtio/virtio-balloon.c
#
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 9639f4e89b..a6ee501051 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -53,6 +53,15 @@ static void chr_read(void *opaque, const void *buf, size_t size)
return;
}
+ /* we can't modify the virtqueue until
+ * our state is fully synced
+ */
+
+ if (!runstate_check(RUN_STATE_RUNNING)) {
+ trace_virtio_rng_cpu_is_stopped(vrng, size);
+ return;
+ }
+
vrng->quota_remaining -= size;
offset = 0;
@@ -61,6 +70,7 @@ static void chr_read(void *opaque, const void *buf, size_t size)
if (!elem) {
break;
}
+ trace_virtio_rng_popped(vrng);
len = iov_from_buf(elem->in_sg, elem->in_num,
0, buf + offset, size - offset);
offset += len;
@@ -120,17 +130,21 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp)
return f;
}
-static int virtio_rng_post_load(void *opaque, int version_id)
+static void virtio_rng_vm_state_change(void *opaque, int running,
+ RunState state)
{
VirtIORNG *vrng = opaque;
+ trace_virtio_rng_vm_state_change(vrng, running, state);
+
/* We may have an element ready but couldn't process it due to a quota
- * limit. Make sure to try again after live migration when the quota may
- * have been reset.
+ * limit or because CPU was stopped. Make sure to try again when the
+ * CPU restart.
*/
- virtio_rng_process(vrng);
- return 0;
+ if (running && is_guest_ready(vrng)) {
+ virtio_rng_process(vrng);
+ }
}
static void check_rate_limit(void *opaque)
@@ -198,6 +212,9 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
check_rate_limit, vrng);
vrng->activate_timer = true;
+
+ vrng->vmstate = qemu_add_vm_change_state_handler(virtio_rng_vm_state_change,
+ vrng);
}
static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp)
@@ -205,6 +222,7 @@ static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp)
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIORNG *vrng = VIRTIO_RNG(dev);
+ qemu_del_vm_change_state_handler(vrng->vmstate);
timer_del(vrng->rate_limit_timer);
timer_free(vrng->rate_limit_timer);
virtio_cleanup(vdev);
@@ -218,7 +236,6 @@ static const VMStateDescription vmstate_virtio_rng = {
VMSTATE_VIRTIO_DEVICE,
VMSTATE_END_OF_LIST()
},
- .post_load = virtio_rng_post_load,
};
static Property virtio_rng_properties[] = {