* [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code
@ 2012-12-13 10:37 Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports Amit Shah
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Amit Shah @ 2012-12-13 10:37 UTC (permalink / raw)
To: Alon Levy; +Cc: Amit Shah, qemu list
This series reworks the post_load code recently introduced to allocate
the structures only when required (i.e. only at load time). This
helps keep the VirtIOSerial struct clean, and use less RAM.
Also rearrange the code in virtio_serial_load() for easier
readability.
Patch 4 fixes a race with the timer going off after a device got
hot-unplugged, and patch 1 uses unsigned int (uint32_t) type to count
ports, as in the rest of the code.
Please review.
Amit Shah (4):
virtio-serial: use uint32_t to count ports
virtio-serial: move active ports loading to separate function
virtio-serial: allocate post_load only at load-time
virtio-serial: delete timer if active during exit
hw/virtio-serial-bus.c | 150 +++++++++++++++++++++++++++++--------------------
1 file changed, 89 insertions(+), 61 deletions(-)
--
1.8.0.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports
2012-12-13 10:37 [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Amit Shah
@ 2012-12-13 10:37 ` Amit Shah
2012-12-14 5:18 ` Rob Landley
2012-12-13 10:37 ` [Qemu-devel] [PATCH 2/4] virtio-serial: move active ports loading to separate function Amit Shah
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Amit Shah @ 2012-12-13 10:37 UTC (permalink / raw)
To: Alon Levy; +Cc: Amit Shah, qemu list
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 155da58..30f450c 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -56,7 +56,7 @@ struct VirtIOSerial {
struct {
QEMUTimer *timer;
- int nr_active_ports;
+ uint32_t nr_active_ports;
struct {
VirtIOSerialPort *port;
uint8_t host_connected;
@@ -637,7 +637,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
static void virtio_serial_post_load_timer_cb(void *opaque)
{
- int i;
+ uint32_t i;
VirtIOSerial *s = opaque;
VirtIOSerialPort *port;
uint8_t host_connected;
--
1.8.0.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/4] virtio-serial: move active ports loading to separate function
2012-12-13 10:37 [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports Amit Shah
@ 2012-12-13 10:37 ` Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 3/4] virtio-serial: allocate post_load only at load-time Amit Shah
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Amit Shah @ 2012-12-13 10:37 UTC (permalink / raw)
To: Alon Levy; +Cc: Amit Shah, qemu list
The virtio_serial_load() function became too big, split the code that
gets the port info from the source into a separate function.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 96 +++++++++++++++++++++++++++++---------------------
1 file changed, 55 insertions(+), 41 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 30f450c..2e0fe3d 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -658,10 +658,60 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
s->post_load.connected = NULL;
}
+static int fetch_active_ports_list(QEMUFile *f, int version_id,
+ VirtIOSerial *s, uint32_t nr_active_ports)
+{
+ uint32_t i;
+
+ s->post_load.nr_active_ports = nr_active_ports;
+ s->post_load.connected =
+ g_malloc0(sizeof(*s->post_load.connected) * nr_active_ports);
+
+ /* Items in struct VirtIOSerialPort */
+ for (i = 0; i < nr_active_ports; i++) {
+ VirtIOSerialPort *port;
+ uint32_t id;
+
+ id = qemu_get_be32(f);
+ port = find_port_by_id(s, id);
+ if (!port) {
+ return -EINVAL;
+ }
+
+ port->guest_connected = qemu_get_byte(f);
+ s->post_load.connected[i].port = port;
+ s->post_load.connected[i].host_connected = qemu_get_byte(f);
+
+ if (version_id > 2) {
+ uint32_t elem_popped;
+
+ qemu_get_be32s(f, &elem_popped);
+ if (elem_popped) {
+ qemu_get_be32s(f, &port->iov_idx);
+ qemu_get_be64s(f, &port->iov_offset);
+
+ qemu_get_buffer(f, (unsigned char *)&port->elem,
+ sizeof(port->elem));
+ virtqueue_map_sg(port->elem.in_sg, port->elem.in_addr,
+ port->elem.in_num, 1);
+ virtqueue_map_sg(port->elem.out_sg, port->elem.out_addr,
+ port->elem.out_num, 1);
+
+ /*
+ * Port was throttled on source machine. Let's
+ * unthrottle it here so data starts flowing again.
+ */
+ virtio_serial_throttle_port(port, false);
+ }
+ }
+ }
+ qemu_mod_timer(s->post_load.timer, 1);
+ return 0;
+}
+
static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
{
VirtIOSerial *s = opaque;
- VirtIOSerialPort *port;
uint32_t max_nr_ports, nr_active_ports, ports_map;
unsigned int i;
int ret;
@@ -705,48 +755,12 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_be32s(f, &nr_active_ports);
- s->post_load.nr_active_ports = nr_active_ports;
- s->post_load.connected =
- g_malloc0(sizeof(*s->post_load.connected) * nr_active_ports);
-
- /* Items in struct VirtIOSerialPort */
- for (i = 0; i < nr_active_ports; i++) {
- uint32_t id;
-
- id = qemu_get_be32(f);
- port = find_port_by_id(s, id);
- if (!port) {
- return -EINVAL;
- }
-
- port->guest_connected = qemu_get_byte(f);
- s->post_load.connected[i].port = port;
- s->post_load.connected[i].host_connected = qemu_get_byte(f);
-
- if (version_id > 2) {
- uint32_t elem_popped;
-
- qemu_get_be32s(f, &elem_popped);
- if (elem_popped) {
- qemu_get_be32s(f, &port->iov_idx);
- qemu_get_be64s(f, &port->iov_offset);
-
- qemu_get_buffer(f, (unsigned char *)&port->elem,
- sizeof(port->elem));
- virtqueue_map_sg(port->elem.in_sg, port->elem.in_addr,
- port->elem.in_num, 1);
- virtqueue_map_sg(port->elem.out_sg, port->elem.out_addr,
- port->elem.out_num, 1);
-
- /*
- * Port was throttled on source machine. Let's
- * unthrottle it here so data starts flowing again.
- */
- virtio_serial_throttle_port(port, false);
- }
+ if (nr_active_ports) {
+ ret = fetch_active_ports_list(f, version_id, s, nr_active_ports);
+ if (ret) {
+ return ret;
}
}
- qemu_mod_timer(s->post_load.timer, 1);
return 0;
}
--
1.8.0.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/4] virtio-serial: allocate post_load only at load-time
2012-12-13 10:37 [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 2/4] virtio-serial: move active ports loading to separate function Amit Shah
@ 2012-12-13 10:37 ` Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 4/4] virtio-serial: delete timer if active during exit Amit Shah
2012-12-13 10:46 ` [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Alon Levy
4 siblings, 0 replies; 7+ messages in thread
From: Amit Shah @ 2012-12-13 10:37 UTC (permalink / raw)
To: Alon Levy; +Cc: Amit Shah, qemu list
This saves us a few bytes in the VirtIOSerial struct. Not a big
savings, but since the entire structure is used only during a short
while after migration, it's helpful to keep the struct cleaner and
smaller.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 63 ++++++++++++++++++++++++++++++--------------------
1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 2e0fe3d..09d4659 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -36,6 +36,15 @@ struct VirtIOSerialBus {
uint32_t max_nr_ports;
};
+typedef struct VirtIOSerialPostLoad {
+ QEMUTimer *timer;
+ uint32_t nr_active_ports;
+ struct {
+ VirtIOSerialPort *port;
+ uint8_t host_connected;
+ } *connected;
+} VirtIOSerialPostLoad;
+
struct VirtIOSerial {
VirtIODevice vdev;
@@ -54,14 +63,7 @@ struct VirtIOSerial {
struct virtio_console_config config;
- struct {
- QEMUTimer *timer;
- uint32_t nr_active_ports;
- struct {
- VirtIOSerialPort *port;
- uint8_t host_connected;
- } *connected;
- } post_load;
+ struct VirtIOSerialPostLoad *post_load;
};
static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
@@ -642,9 +644,12 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
VirtIOSerialPort *port;
uint8_t host_connected;
- for (i = 0 ; i < s->post_load.nr_active_ports; ++i) {
- port = s->post_load.connected[i].port;
- host_connected = s->post_load.connected[i].host_connected;
+ if (!s->post_load) {
+ return;
+ }
+ for (i = 0 ; i < s->post_load->nr_active_ports; ++i) {
+ port = s->post_load->connected[i].port;
+ host_connected = s->post_load->connected[i].host_connected;
if (host_connected != port->host_connected) {
/*
* We have to let the guest know of the host connection
@@ -654,8 +659,10 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
port->host_connected);
}
}
- g_free(s->post_load.connected);
- s->post_load.connected = NULL;
+ g_free(s->post_load->connected);
+ qemu_free_timer(s->post_load->timer);
+ g_free(s->post_load);
+ s->post_load = NULL;
}
static int fetch_active_ports_list(QEMUFile *f, int version_id,
@@ -663,9 +670,14 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
{
uint32_t i;
- s->post_load.nr_active_ports = nr_active_ports;
- s->post_load.connected =
- g_malloc0(sizeof(*s->post_load.connected) * nr_active_ports);
+ s->post_load = g_malloc0(sizeof(*s->post_load));
+ s->post_load->nr_active_ports = nr_active_ports;
+ s->post_load->connected =
+ g_malloc0(sizeof(*s->post_load->connected) * nr_active_ports);
+
+ s->post_load->timer = qemu_new_timer_ns(vm_clock,
+ virtio_serial_post_load_timer_cb,
+ s);
/* Items in struct VirtIOSerialPort */
for (i = 0; i < nr_active_ports; i++) {
@@ -679,8 +691,8 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
}
port->guest_connected = qemu_get_byte(f);
- s->post_load.connected[i].port = port;
- s->post_load.connected[i].host_connected = qemu_get_byte(f);
+ s->post_load->connected[i].port = port;
+ s->post_load->connected[i].host_connected = qemu_get_byte(f);
if (version_id > 2) {
uint32_t elem_popped;
@@ -705,7 +717,7 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
}
}
}
- qemu_mod_timer(s->post_load.timer, 1);
+ qemu_mod_timer(s->post_load->timer, 1);
return 0;
}
@@ -1003,6 +1015,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
vser->qdev = dev;
+ vser->post_load = NULL;
+
/*
* Register for the savevm section with the virtio-console name
* to preserve backward compat
@@ -1010,9 +1024,6 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
virtio_serial_load, vser);
- vser->post_load.timer = qemu_new_timer_ns(vm_clock,
- virtio_serial_post_load_timer_cb, vser);
-
return vdev;
}
@@ -1025,9 +1036,11 @@ void virtio_serial_exit(VirtIODevice *vdev)
g_free(vser->ivqs);
g_free(vser->ovqs);
g_free(vser->ports_map);
- g_free(vser->post_load.connected);
- qemu_free_timer(vser->post_load.timer);
-
+ if (vser->post_load) {
+ g_free(vser->post_load->connected);
+ qemu_free_timer(vser->post_load->timer);
+ g_free(vser->post_load);
+ }
virtio_cleanup(vdev);
}
--
1.8.0.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/4] virtio-serial: delete timer if active during exit
2012-12-13 10:37 [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Amit Shah
` (2 preceding siblings ...)
2012-12-13 10:37 ` [Qemu-devel] [PATCH 3/4] virtio-serial: allocate post_load only at load-time Amit Shah
@ 2012-12-13 10:37 ` Amit Shah
2012-12-13 10:46 ` [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Alon Levy
4 siblings, 0 replies; 7+ messages in thread
From: Amit Shah @ 2012-12-13 10:37 UTC (permalink / raw)
To: Alon Levy; +Cc: Amit Shah, qemu list
The post_load timer was being freed, but not deleted. This could cause
problems when the timer is armed, but the device is hot-unplugged before
the callback is executed.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-serial-bus.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 09d4659..fc0166c 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -1038,6 +1038,7 @@ void virtio_serial_exit(VirtIODevice *vdev)
g_free(vser->ports_map);
if (vser->post_load) {
g_free(vser->post_load->connected);
+ qemu_del_timer(vser->post_load->timer);
qemu_free_timer(vser->post_load->timer);
g_free(vser->post_load);
}
--
1.8.0.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code
2012-12-13 10:37 [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Amit Shah
` (3 preceding siblings ...)
2012-12-13 10:37 ` [Qemu-devel] [PATCH 4/4] virtio-serial: delete timer if active during exit Amit Shah
@ 2012-12-13 10:46 ` Alon Levy
4 siblings, 0 replies; 7+ messages in thread
From: Alon Levy @ 2012-12-13 10:46 UTC (permalink / raw)
To: Amit Shah; +Cc: qemu list
All looks good.
Reviewed-by: Alon Levy <alevy@redhat.com>
----- Original Message -----
> This series reworks the post_load code recently introduced to
> allocate
> the structures only when required (i.e. only at load time). This
> helps keep the VirtIOSerial struct clean, and use less RAM.
>
> Also rearrange the code in virtio_serial_load() for easier
> readability.
>
> Patch 4 fixes a race with the timer going off after a device got
> hot-unplugged, and patch 1 uses unsigned int (uint32_t) type to count
> ports, as in the rest of the code.
>
> Please review.
>
> Amit Shah (4):
> virtio-serial: use uint32_t to count ports
> virtio-serial: move active ports loading to separate function
> virtio-serial: allocate post_load only at load-time
> virtio-serial: delete timer if active during exit
>
> hw/virtio-serial-bus.c | 150
> +++++++++++++++++++++++++++++--------------------
> 1 file changed, 89 insertions(+), 61 deletions(-)
>
> --
> 1.8.0.2
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports
2012-12-13 10:37 ` [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports Amit Shah
@ 2012-12-14 5:18 ` Rob Landley
0 siblings, 0 replies; 7+ messages in thread
From: Rob Landley @ 2012-12-14 5:18 UTC (permalink / raw)
To: Amit Shah; +Cc: Alon Levy, qemu list
Speaking of virtio-serial, is there a way to get virtio serial ports to
attach to qemu's stdin/stdout the way other serial ports can (and which
is the default with --nographic for conventional serial ports), or do
you still have to make a magic char device on the host?
I never understood why _using_ virtio serial ports was so different,
but it's been about a year since I looked at them (because they were so
different).
Rob
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-12-14 5:18 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-13 10:37 [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 1/4] virtio-serial: use uint32_t to count ports Amit Shah
2012-12-14 5:18 ` Rob Landley
2012-12-13 10:37 ` [Qemu-devel] [PATCH 2/4] virtio-serial: move active ports loading to separate function Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 3/4] virtio-serial: allocate post_load only at load-time Amit Shah
2012-12-13 10:37 ` [Qemu-devel] [PATCH 4/4] virtio-serial: delete timer if active during exit Amit Shah
2012-12-13 10:46 ` [Qemu-devel] [PATCH 0/4] virtio-serial: Rework, fix post_load code Alon Levy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).