* [Qemu-devel] [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy
@ 2011-02-03 6:17 Amit Shah
2011-02-03 6:17 ` [Qemu-devel] [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control Amit Shah
2011-02-07 15:46 ` [Qemu-devel] Re: [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy Alex Williamson
0 siblings, 2 replies; 5+ messages in thread
From: Amit Shah @ 2011-02-03 6:17 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Alex Williamson, Michael S. Tsirkin
Instead of using a single variable to pass to the virtio_serial_init
function, use a struct so that expanding the number of variables to be
passed on later is easier.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/virtio-pci.c | 12 ++++++------
hw/virtio-serial-bus.c | 16 ++++++++--------
hw/virtio-serial.h | 5 +++++
hw/virtio.h | 3 ++-
4 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 3911b09..952b5d2 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -18,6 +18,7 @@
#include "virtio.h"
#include "virtio-blk.h"
#include "virtio-net.h"
+#include "virtio-serial.h"
#include "pci.h"
#include "qemu-error.h"
#include "msix.h"
@@ -109,8 +110,7 @@ typedef struct {
#ifdef CONFIG_LINUX
V9fsConf fsconf;
#endif
- /* Max. number of ports we can have for a the virtio-serial device */
- uint32_t max_virtserial_ports;
+ virtio_serial_conf serial;
virtio_net_conf net;
bool ioeventfd_disabled;
bool ioeventfd_started;
@@ -770,12 +770,12 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev)
proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */
proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
- vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports);
+ vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
if (!vdev) {
return -1;
}
vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
- ? proxy->max_virtserial_ports + 1
+ ? proxy->serial.max_virtserial_ports + 1
: proxy->nvectors;
virtio_init_pci(proxy, vdev,
PCI_VENDOR_ID_REDHAT_QUMRANET,
@@ -902,8 +902,8 @@ static PCIDeviceInfo virtio_info[] = {
DEV_NVECTORS_UNSPECIFIED),
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
- DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports,
- 31),
+ DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
+ serial.max_virtserial_ports, 31),
DEFINE_PROP_END_OF_LIST(),
},
.qdev.reset = virtio_pci_reset,
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 09e22aa..1753785 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -811,19 +811,19 @@ void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
qdev_register(&info->qdev);
}
-VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
+VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
{
VirtIOSerial *vser;
VirtIODevice *vdev;
uint32_t i, max_supported_ports;
- if (!max_nr_ports)
+ if (!conf->max_virtserial_ports)
return NULL;
/* Each port takes 2 queues, and one pair is for the control queue */
max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1;
- if (max_nr_ports > max_supported_ports) {
+ if (conf->max_virtserial_ports > max_supported_ports) {
error_report("maximum ports supported: %u", max_supported_ports);
return NULL;
}
@@ -839,9 +839,9 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
vser->bus->vser = vser;
QTAILQ_INIT(&vser->ports);
- vser->bus->max_nr_ports = max_nr_ports;
- vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
- vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
+ vser->bus->max_nr_ports = conf->max_virtserial_ports;
+ vser->ivqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
+ vser->ovqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
/* Add a queue for host to guest transfers for port 0 (backward compat) */
vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
@@ -866,8 +866,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
}
- vser->config.max_nr_ports = max_nr_ports;
- vser->ports_map = qemu_mallocz(((max_nr_ports + 31) / 32)
+ vser->config.max_nr_ports = conf->max_virtserial_ports;
+ vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
* sizeof(vser->ports_map[0]));
/*
* Reserve location 0 for a console port for backward compat
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index a308196..de624c3 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -45,6 +45,11 @@ struct virtio_console_control {
uint16_t value; /* Extra information for the key */
};
+struct virtio_serial_conf {
+ /* Max. number of ports we can have for a the virtio-serial device */
+ uint32_t max_virtserial_ports;
+};
+
/* Some events for the internal messages (control packets) */
#define VIRTIO_CONSOLE_DEVICE_READY 0
#define VIRTIO_CONSOLE_PORT_ADD 1
diff --git a/hw/virtio.h b/hw/virtio.h
index 31d16e1..d0920a8 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -195,7 +195,8 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
struct virtio_net_conf;
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
struct virtio_net_conf *net);
-VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports);
+typedef struct virtio_serial_conf virtio_serial_conf;
+VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
VirtIODevice *virtio_balloon_init(DeviceState *dev);
#ifdef CONFIG_LINUX
VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
--
1.7.3.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control
2011-02-03 6:17 [Qemu-devel] [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy Amit Shah
@ 2011-02-03 6:17 ` Amit Shah
2011-02-07 15:47 ` [Qemu-devel] " Alex Williamson
2011-02-07 15:46 ` [Qemu-devel] Re: [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy Alex Williamson
1 sibling, 1 reply; 5+ messages in thread
From: Amit Shah @ 2011-02-03 6:17 UTC (permalink / raw)
To: qemu list; +Cc: Amit Shah, Alex Williamson, Michael S. Tsirkin
Add a compat property for older machine types. When this is used (via
-M pc-0.13, for example), the new flow control mechanisms will not be
used. This is done to keep migration from a machine started with older
type on a pc-0.14+ qemu to an older machine working.
The property is named 'flow_control' and defaults to on.
Reported-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
hw/pc_piix.c | 16 ++++++++++
hw/virtio-pci.c | 2 +
hw/virtio-serial-bus.c | 77 +++++++++++++++++++++++++++++++++++++++++-------
hw/virtio-serial.h | 12 +++++++
4 files changed, 96 insertions(+), 11 deletions(-)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7b74473..05b0449 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -243,6 +243,10 @@ static QEMUMachine pc_machine_v0_13 = {
.driver = "PCI",
.property = "command_serr_enable",
.value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "flow_control",
+ .value = stringify(0),
},
{ /* end of list */ }
},
@@ -263,6 +267,10 @@ static QEMUMachine pc_machine_v0_12 = {
.property = "vectors",
.value = stringify(0),
},{
+ .driver = "virtio-serial-pci",
+ .property = "flow_control",
+ .value = stringify(0),
+ },{
.driver = "VGA",
.property = "rombar",
.value = stringify(0),
@@ -298,6 +306,10 @@ static QEMUMachine pc_machine_v0_11 = {
.property = "vectors",
.value = stringify(0),
},{
+ .driver = "virtio-serial-pci",
+ .property = "flow_control",
+ .value = stringify(0),
+ },{
.driver = "ide-drive",
.property = "ver",
.value = "0.11",
@@ -341,6 +353,10 @@ static QEMUMachine pc_machine_v0_10 = {
.property = "vectors",
.value = stringify(0),
},{
+ .driver = "virtio-serial-pci",
+ .property = "flow_control",
+ .value = stringify(0),
+ },{
.driver = "virtio-net-pci",
.property = "vectors",
.value = stringify(0),
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 952b5d2..530ce9d 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -904,6 +904,8 @@ static PCIDeviceInfo virtio_info[] = {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
serial.max_virtserial_ports, 31),
+ DEFINE_PROP_UINT32("flow_control", VirtIOPCIProxy,
+ serial.flow_control, 1),
DEFINE_PROP_END_OF_LIST(),
},
.qdev.reset = virtio_pci_reset,
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 1753785..f681646 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -49,6 +49,8 @@ struct VirtIOSerial {
uint32_t *ports_map;
struct virtio_console_config config;
+
+ bool flow_control;
};
static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
@@ -123,12 +125,46 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
virtio_notify(vdev, vq);
}
+static void do_flush_queued_data_no_flow_control(VirtIOSerialPort *port,
+ VirtQueue *vq,
+ VirtIODevice *vdev)
+{
+ VirtQueueElement elem;
+
+ while (!port->throttled && virtqueue_pop(vq, &elem)) {
+ uint8_t *buf;
+ size_t ret, buf_size;
+
+ buf_size = iov_size(elem.out_sg, elem.out_num);
+ buf = qemu_malloc(buf_size);
+ ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
+
+ /*
+ * have_data has been modified to return the number of bytes
+ * successfully consumed. We can't act upon that information
+ * in the no-flow-control implementation, so we'll discard it
+ * here. No callers currently use flow control, but they
+ * should take this into account for backward compatibility.
+ */
+ port->info->have_data(port, buf, ret);
+ qemu_free(buf);
+
+ virtqueue_push(vq, &elem, 0);
+ }
+ virtio_notify(vdev, vq);
+}
+
static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
VirtIODevice *vdev)
{
assert(port);
assert(virtio_queue_ready(vq));
+ if (!virtio_serial_flow_control_enabled(port)) {
+ do_flush_queued_data_no_flow_control(port, vq, vdev);
+ return;
+ }
+
while (!port->throttled) {
unsigned int i;
@@ -296,6 +332,15 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
flush_queued_data(port);
}
+bool virtio_serial_flow_control_enabled(VirtIOSerialPort *port)
+{
+ if (!port) {
+ return false;
+ }
+
+ return port->vser->flow_control;
+}
+
/* Guest wants to notify us of some event */
static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
{
@@ -533,17 +578,19 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
qemu_put_byte(f, port->guest_connected);
qemu_put_byte(f, port->host_connected);
- elem_popped = 0;
- if (port->elem.out_num) {
- elem_popped = 1;
- }
- qemu_put_be32s(f, &elem_popped);
- if (elem_popped) {
- qemu_put_be32s(f, &port->iov_idx);
- qemu_put_be64s(f, &port->iov_offset);
+ if (virtio_serial_flow_control_enabled(port)) {
+ elem_popped = 0;
+ if (port->elem.out_num) {
+ elem_popped = 1;
+ }
+ qemu_put_be32s(f, &elem_popped);
+ if (elem_popped) {
+ qemu_put_be32s(f, &port->iov_idx);
+ qemu_put_be64s(f, &port->iov_offset);
- qemu_put_buffer(f, (unsigned char *)&port->elem,
- sizeof(port->elem));
+ qemu_put_buffer(f, (unsigned char *)&port->elem,
+ sizeof(port->elem));
+ }
}
}
}
@@ -816,6 +863,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
VirtIOSerial *vser;
VirtIODevice *vdev;
uint32_t i, max_supported_ports;
+ unsigned int savevm_ver;
if (!conf->max_virtserial_ports)
return NULL;
@@ -881,11 +929,18 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
vser->qdev = dev;
+ vser->flow_control = true;
+ savevm_ver = 3;
+ if (!conf->flow_control) {
+ vser->flow_control = false;
+ savevm_ver = 2;
+ }
+
/*
* Register for the savevm section with the virtio-console name
* to preserve backward compat
*/
- register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
+ register_savevm(dev, "virtio-console", -1, savevm_ver, virtio_serial_save,
virtio_serial_load, vser);
return vdev;
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index de624c3..57d2dee 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -48,6 +48,13 @@ struct virtio_console_control {
struct virtio_serial_conf {
/* Max. number of ports we can have for a the virtio-serial device */
uint32_t max_virtserial_ports;
+
+ /*
+ * Should this device behave the way it did in prior to pc-0.14
+ * (ie. no flow control)? This will be necessary to allow
+ * migrations from a pre-0.14-machine type to older qemu code
+ */
+ uint32_t flow_control;
};
/* Some events for the internal messages (control packets) */
@@ -204,4 +211,9 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
*/
void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
+/*
+ * Does this machine type disable the use of flow control?
+ */
+bool virtio_serial_flow_control_enabled(VirtIOSerialPort *port);
+
#endif
--
1.7.3.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] Re: [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy
2011-02-03 6:17 [Qemu-devel] [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy Amit Shah
2011-02-03 6:17 ` [Qemu-devel] [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control Amit Shah
@ 2011-02-07 15:46 ` Alex Williamson
1 sibling, 0 replies; 5+ messages in thread
From: Alex Williamson @ 2011-02-07 15:46 UTC (permalink / raw)
To: Amit Shah; +Cc: qemu list, Michael S. Tsirkin
On Thu, 2011-02-03 at 11:47 +0530, Amit Shah wrote:
> Instead of using a single variable to pass to the virtio_serial_init
> function, use a struct so that expanding the number of variables to be
> passed on later is easier.
>
> Signed-off-by: Amit Shah <amit.shah@redhat.com>
> ---
> hw/virtio-pci.c | 12 ++++++------
> hw/virtio-serial-bus.c | 16 ++++++++--------
> hw/virtio-serial.h | 5 +++++
> hw/virtio.h | 3 ++-
> 4 files changed, 21 insertions(+), 15 deletions(-)
Acked-by: Alex Williamson <alex.williamson@redhat.com>
> diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
> index 3911b09..952b5d2 100644
> --- a/hw/virtio-pci.c
> +++ b/hw/virtio-pci.c
> @@ -18,6 +18,7 @@
> #include "virtio.h"
> #include "virtio-blk.h"
> #include "virtio-net.h"
> +#include "virtio-serial.h"
> #include "pci.h"
> #include "qemu-error.h"
> #include "msix.h"
> @@ -109,8 +110,7 @@ typedef struct {
> #ifdef CONFIG_LINUX
> V9fsConf fsconf;
> #endif
> - /* Max. number of ports we can have for a the virtio-serial device */
> - uint32_t max_virtserial_ports;
> + virtio_serial_conf serial;
> virtio_net_conf net;
> bool ioeventfd_disabled;
> bool ioeventfd_started;
> @@ -770,12 +770,12 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev)
> proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */
> proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
>
> - vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports);
> + vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
> if (!vdev) {
> return -1;
> }
> vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
> - ? proxy->max_virtserial_ports + 1
> + ? proxy->serial.max_virtserial_ports + 1
> : proxy->nvectors;
> virtio_init_pci(proxy, vdev,
> PCI_VENDOR_ID_REDHAT_QUMRANET,
> @@ -902,8 +902,8 @@ static PCIDeviceInfo virtio_info[] = {
> DEV_NVECTORS_UNSPECIFIED),
> DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
> DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
> - DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports,
> - 31),
> + DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
> + serial.max_virtserial_ports, 31),
> DEFINE_PROP_END_OF_LIST(),
> },
> .qdev.reset = virtio_pci_reset,
> diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
> index 09e22aa..1753785 100644
> --- a/hw/virtio-serial-bus.c
> +++ b/hw/virtio-serial-bus.c
> @@ -811,19 +811,19 @@ void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
> qdev_register(&info->qdev);
> }
>
> -VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
> +VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
> {
> VirtIOSerial *vser;
> VirtIODevice *vdev;
> uint32_t i, max_supported_ports;
>
> - if (!max_nr_ports)
> + if (!conf->max_virtserial_ports)
> return NULL;
>
> /* Each port takes 2 queues, and one pair is for the control queue */
> max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1;
>
> - if (max_nr_ports > max_supported_ports) {
> + if (conf->max_virtserial_ports > max_supported_ports) {
> error_report("maximum ports supported: %u", max_supported_ports);
> return NULL;
> }
> @@ -839,9 +839,9 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
> vser->bus->vser = vser;
> QTAILQ_INIT(&vser->ports);
>
> - vser->bus->max_nr_ports = max_nr_ports;
> - vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
> - vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
> + vser->bus->max_nr_ports = conf->max_virtserial_ports;
> + vser->ivqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
> + vser->ovqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
>
> /* Add a queue for host to guest transfers for port 0 (backward compat) */
> vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
> @@ -866,8 +866,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
> vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
> }
>
> - vser->config.max_nr_ports = max_nr_ports;
> - vser->ports_map = qemu_mallocz(((max_nr_ports + 31) / 32)
> + vser->config.max_nr_ports = conf->max_virtserial_ports;
> + vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
> * sizeof(vser->ports_map[0]));
> /*
> * Reserve location 0 for a console port for backward compat
> diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
> index a308196..de624c3 100644
> --- a/hw/virtio-serial.h
> +++ b/hw/virtio-serial.h
> @@ -45,6 +45,11 @@ struct virtio_console_control {
> uint16_t value; /* Extra information for the key */
> };
>
> +struct virtio_serial_conf {
> + /* Max. number of ports we can have for a the virtio-serial device */
> + uint32_t max_virtserial_ports;
> +};
> +
> /* Some events for the internal messages (control packets) */
> #define VIRTIO_CONSOLE_DEVICE_READY 0
> #define VIRTIO_CONSOLE_PORT_ADD 1
> diff --git a/hw/virtio.h b/hw/virtio.h
> index 31d16e1..d0920a8 100644
> --- a/hw/virtio.h
> +++ b/hw/virtio.h
> @@ -195,7 +195,8 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
> struct virtio_net_conf;
> VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
> struct virtio_net_conf *net);
> -VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports);
> +typedef struct virtio_serial_conf virtio_serial_conf;
> +VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
> VirtIODevice *virtio_balloon_init(DeviceState *dev);
> #ifdef CONFIG_LINUX
> VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] Re: [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control
2011-02-03 6:17 ` [Qemu-devel] [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control Amit Shah
@ 2011-02-07 15:47 ` Alex Williamson
2011-02-07 16:10 ` Michael S. Tsirkin
0 siblings, 1 reply; 5+ messages in thread
From: Alex Williamson @ 2011-02-07 15:47 UTC (permalink / raw)
To: Amit Shah; +Cc: qemu list, Michael S. Tsirkin
On Thu, 2011-02-03 at 11:47 +0530, Amit Shah wrote:
> Add a compat property for older machine types. When this is used (via
> -M pc-0.13, for example), the new flow control mechanisms will not be
> used. This is done to keep migration from a machine started with older
> type on a pc-0.14+ qemu to an older machine working.
>
> The property is named 'flow_control' and defaults to on.
>
> Reported-by: Alex Williamson <alex.williamson@redhat.com>
> Signed-off-by: Amit Shah <amit.shah@redhat.com>
> ---
> hw/pc_piix.c | 16 ++++++++++
> hw/virtio-pci.c | 2 +
> hw/virtio-serial-bus.c | 77 +++++++++++++++++++++++++++++++++++++++++-------
> hw/virtio-serial.h | 12 +++++++
> 4 files changed, 96 insertions(+), 11 deletions(-)
Acked-by: Alex Williamson <alex.williamson@redhat.com>
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index 7b74473..05b0449 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -243,6 +243,10 @@ static QEMUMachine pc_machine_v0_13 = {
> .driver = "PCI",
> .property = "command_serr_enable",
> .value = "off",
> + },{
> + .driver = "virtio-serial-pci",
> + .property = "flow_control",
> + .value = stringify(0),
> },
> { /* end of list */ }
> },
> @@ -263,6 +267,10 @@ static QEMUMachine pc_machine_v0_12 = {
> .property = "vectors",
> .value = stringify(0),
> },{
> + .driver = "virtio-serial-pci",
> + .property = "flow_control",
> + .value = stringify(0),
> + },{
> .driver = "VGA",
> .property = "rombar",
> .value = stringify(0),
> @@ -298,6 +306,10 @@ static QEMUMachine pc_machine_v0_11 = {
> .property = "vectors",
> .value = stringify(0),
> },{
> + .driver = "virtio-serial-pci",
> + .property = "flow_control",
> + .value = stringify(0),
> + },{
> .driver = "ide-drive",
> .property = "ver",
> .value = "0.11",
> @@ -341,6 +353,10 @@ static QEMUMachine pc_machine_v0_10 = {
> .property = "vectors",
> .value = stringify(0),
> },{
> + .driver = "virtio-serial-pci",
> + .property = "flow_control",
> + .value = stringify(0),
> + },{
> .driver = "virtio-net-pci",
> .property = "vectors",
> .value = stringify(0),
> diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
> index 952b5d2..530ce9d 100644
> --- a/hw/virtio-pci.c
> +++ b/hw/virtio-pci.c
> @@ -904,6 +904,8 @@ static PCIDeviceInfo virtio_info[] = {
> DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
> DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
> serial.max_virtserial_ports, 31),
> + DEFINE_PROP_UINT32("flow_control", VirtIOPCIProxy,
> + serial.flow_control, 1),
> DEFINE_PROP_END_OF_LIST(),
> },
> .qdev.reset = virtio_pci_reset,
> diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
> index 1753785..f681646 100644
> --- a/hw/virtio-serial-bus.c
> +++ b/hw/virtio-serial-bus.c
> @@ -49,6 +49,8 @@ struct VirtIOSerial {
> uint32_t *ports_map;
>
> struct virtio_console_config config;
> +
> + bool flow_control;
> };
>
> static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
> @@ -123,12 +125,46 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
> virtio_notify(vdev, vq);
> }
>
> +static void do_flush_queued_data_no_flow_control(VirtIOSerialPort *port,
> + VirtQueue *vq,
> + VirtIODevice *vdev)
> +{
> + VirtQueueElement elem;
> +
> + while (!port->throttled && virtqueue_pop(vq, &elem)) {
> + uint8_t *buf;
> + size_t ret, buf_size;
> +
> + buf_size = iov_size(elem.out_sg, elem.out_num);
> + buf = qemu_malloc(buf_size);
> + ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
> +
> + /*
> + * have_data has been modified to return the number of bytes
> + * successfully consumed. We can't act upon that information
> + * in the no-flow-control implementation, so we'll discard it
> + * here. No callers currently use flow control, but they
> + * should take this into account for backward compatibility.
> + */
> + port->info->have_data(port, buf, ret);
> + qemu_free(buf);
> +
> + virtqueue_push(vq, &elem, 0);
> + }
> + virtio_notify(vdev, vq);
> +}
> +
> static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
> VirtIODevice *vdev)
> {
> assert(port);
> assert(virtio_queue_ready(vq));
>
> + if (!virtio_serial_flow_control_enabled(port)) {
> + do_flush_queued_data_no_flow_control(port, vq, vdev);
> + return;
> + }
> +
> while (!port->throttled) {
> unsigned int i;
>
> @@ -296,6 +332,15 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
> flush_queued_data(port);
> }
>
> +bool virtio_serial_flow_control_enabled(VirtIOSerialPort *port)
> +{
> + if (!port) {
> + return false;
> + }
> +
> + return port->vser->flow_control;
> +}
> +
> /* Guest wants to notify us of some event */
> static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
> {
> @@ -533,17 +578,19 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
> qemu_put_byte(f, port->guest_connected);
> qemu_put_byte(f, port->host_connected);
>
> - elem_popped = 0;
> - if (port->elem.out_num) {
> - elem_popped = 1;
> - }
> - qemu_put_be32s(f, &elem_popped);
> - if (elem_popped) {
> - qemu_put_be32s(f, &port->iov_idx);
> - qemu_put_be64s(f, &port->iov_offset);
> + if (virtio_serial_flow_control_enabled(port)) {
> + elem_popped = 0;
> + if (port->elem.out_num) {
> + elem_popped = 1;
> + }
> + qemu_put_be32s(f, &elem_popped);
> + if (elem_popped) {
> + qemu_put_be32s(f, &port->iov_idx);
> + qemu_put_be64s(f, &port->iov_offset);
>
> - qemu_put_buffer(f, (unsigned char *)&port->elem,
> - sizeof(port->elem));
> + qemu_put_buffer(f, (unsigned char *)&port->elem,
> + sizeof(port->elem));
> + }
> }
> }
> }
> @@ -816,6 +863,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
> VirtIOSerial *vser;
> VirtIODevice *vdev;
> uint32_t i, max_supported_ports;
> + unsigned int savevm_ver;
>
> if (!conf->max_virtserial_ports)
> return NULL;
> @@ -881,11 +929,18 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
>
> vser->qdev = dev;
>
> + vser->flow_control = true;
> + savevm_ver = 3;
> + if (!conf->flow_control) {
> + vser->flow_control = false;
> + savevm_ver = 2;
> + }
> +
> /*
> * Register for the savevm section with the virtio-console name
> * to preserve backward compat
> */
> - register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
> + register_savevm(dev, "virtio-console", -1, savevm_ver, virtio_serial_save,
> virtio_serial_load, vser);
>
> return vdev;
> diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
> index de624c3..57d2dee 100644
> --- a/hw/virtio-serial.h
> +++ b/hw/virtio-serial.h
> @@ -48,6 +48,13 @@ struct virtio_console_control {
> struct virtio_serial_conf {
> /* Max. number of ports we can have for a the virtio-serial device */
> uint32_t max_virtserial_ports;
> +
> + /*
> + * Should this device behave the way it did in prior to pc-0.14
> + * (ie. no flow control)? This will be necessary to allow
> + * migrations from a pre-0.14-machine type to older qemu code
> + */
> + uint32_t flow_control;
> };
>
> /* Some events for the internal messages (control packets) */
> @@ -204,4 +211,9 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
> */
> void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
>
> +/*
> + * Does this machine type disable the use of flow control?
> + */
> +bool virtio_serial_flow_control_enabled(VirtIOSerialPort *port);
> +
> #endif
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] Re: [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control
2011-02-07 15:47 ` [Qemu-devel] " Alex Williamson
@ 2011-02-07 16:10 ` Michael S. Tsirkin
0 siblings, 0 replies; 5+ messages in thread
From: Michael S. Tsirkin @ 2011-02-07 16:10 UTC (permalink / raw)
To: Alex Williamson; +Cc: Amit Shah, qemu list
On Mon, Feb 07, 2011 at 08:47:11AM -0700, Alex Williamson wrote:
> On Thu, 2011-02-03 at 11:47 +0530, Amit Shah wrote:
> > Add a compat property for older machine types. When this is used (via
> > -M pc-0.13, for example), the new flow control mechanisms will not be
> > used. This is done to keep migration from a machine started with older
> > type on a pc-0.14+ qemu to an older machine working.
> >
> > The property is named 'flow_control' and defaults to on.
> >
> > Reported-by: Alex Williamson <alex.williamson@redhat.com>
> > Signed-off-by: Amit Shah <amit.shah@redhat.com>
> > ---
> > hw/pc_piix.c | 16 ++++++++++
> > hw/virtio-pci.c | 2 +
> > hw/virtio-serial-bus.c | 77 +++++++++++++++++++++++++++++++++++++++++-------
> > hw/virtio-serial.h | 12 +++++++
> > 4 files changed, 96 insertions(+), 11 deletions(-)
>
> Acked-by: Alex Williamson <alex.williamson@redhat.com>
Before merging this, I think we need to have a discussion on
cross version migration. Started a separate thread for that.
> > diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> > index 7b74473..05b0449 100644
> > --- a/hw/pc_piix.c
> > +++ b/hw/pc_piix.c
> > @@ -243,6 +243,10 @@ static QEMUMachine pc_machine_v0_13 = {
> > .driver = "PCI",
> > .property = "command_serr_enable",
> > .value = "off",
> > + },{
> > + .driver = "virtio-serial-pci",
> > + .property = "flow_control",
> > + .value = stringify(0),
> > },
> > { /* end of list */ }
> > },
> > @@ -263,6 +267,10 @@ static QEMUMachine pc_machine_v0_12 = {
> > .property = "vectors",
> > .value = stringify(0),
> > },{
> > + .driver = "virtio-serial-pci",
> > + .property = "flow_control",
> > + .value = stringify(0),
> > + },{
> > .driver = "VGA",
> > .property = "rombar",
> > .value = stringify(0),
> > @@ -298,6 +306,10 @@ static QEMUMachine pc_machine_v0_11 = {
> > .property = "vectors",
> > .value = stringify(0),
> > },{
> > + .driver = "virtio-serial-pci",
> > + .property = "flow_control",
> > + .value = stringify(0),
> > + },{
> > .driver = "ide-drive",
> > .property = "ver",
> > .value = "0.11",
> > @@ -341,6 +353,10 @@ static QEMUMachine pc_machine_v0_10 = {
> > .property = "vectors",
> > .value = stringify(0),
> > },{
> > + .driver = "virtio-serial-pci",
> > + .property = "flow_control",
> > + .value = stringify(0),
> > + },{
> > .driver = "virtio-net-pci",
> > .property = "vectors",
> > .value = stringify(0),
> > diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
> > index 952b5d2..530ce9d 100644
> > --- a/hw/virtio-pci.c
> > +++ b/hw/virtio-pci.c
> > @@ -904,6 +904,8 @@ static PCIDeviceInfo virtio_info[] = {
> > DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
> > DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
> > serial.max_virtserial_ports, 31),
> > + DEFINE_PROP_UINT32("flow_control", VirtIOPCIProxy,
> > + serial.flow_control, 1),
> > DEFINE_PROP_END_OF_LIST(),
> > },
> > .qdev.reset = virtio_pci_reset,
> > diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
> > index 1753785..f681646 100644
> > --- a/hw/virtio-serial-bus.c
> > +++ b/hw/virtio-serial-bus.c
> > @@ -49,6 +49,8 @@ struct VirtIOSerial {
> > uint32_t *ports_map;
> >
> > struct virtio_console_config config;
> > +
> > + bool flow_control;
> > };
> >
> > static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
> > @@ -123,12 +125,46 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
> > virtio_notify(vdev, vq);
> > }
> >
> > +static void do_flush_queued_data_no_flow_control(VirtIOSerialPort *port,
> > + VirtQueue *vq,
> > + VirtIODevice *vdev)
> > +{
> > + VirtQueueElement elem;
> > +
> > + while (!port->throttled && virtqueue_pop(vq, &elem)) {
> > + uint8_t *buf;
> > + size_t ret, buf_size;
> > +
> > + buf_size = iov_size(elem.out_sg, elem.out_num);
> > + buf = qemu_malloc(buf_size);
> > + ret = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, buf_size);
> > +
> > + /*
> > + * have_data has been modified to return the number of bytes
> > + * successfully consumed. We can't act upon that information
> > + * in the no-flow-control implementation, so we'll discard it
> > + * here. No callers currently use flow control, but they
> > + * should take this into account for backward compatibility.
> > + */
> > + port->info->have_data(port, buf, ret);
> > + qemu_free(buf);
> > +
> > + virtqueue_push(vq, &elem, 0);
> > + }
> > + virtio_notify(vdev, vq);
> > +}
> > +
> > static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
> > VirtIODevice *vdev)
> > {
> > assert(port);
> > assert(virtio_queue_ready(vq));
> >
> > + if (!virtio_serial_flow_control_enabled(port)) {
> > + do_flush_queued_data_no_flow_control(port, vq, vdev);
> > + return;
> > + }
> > +
> > while (!port->throttled) {
> > unsigned int i;
> >
> > @@ -296,6 +332,15 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
> > flush_queued_data(port);
> > }
> >
> > +bool virtio_serial_flow_control_enabled(VirtIOSerialPort *port)
> > +{
> > + if (!port) {
> > + return false;
> > + }
> > +
> > + return port->vser->flow_control;
> > +}
> > +
> > /* Guest wants to notify us of some event */
> > static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
> > {
> > @@ -533,17 +578,19 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
> > qemu_put_byte(f, port->guest_connected);
> > qemu_put_byte(f, port->host_connected);
> >
> > - elem_popped = 0;
> > - if (port->elem.out_num) {
> > - elem_popped = 1;
> > - }
> > - qemu_put_be32s(f, &elem_popped);
> > - if (elem_popped) {
> > - qemu_put_be32s(f, &port->iov_idx);
> > - qemu_put_be64s(f, &port->iov_offset);
> > + if (virtio_serial_flow_control_enabled(port)) {
> > + elem_popped = 0;
> > + if (port->elem.out_num) {
> > + elem_popped = 1;
> > + }
> > + qemu_put_be32s(f, &elem_popped);
> > + if (elem_popped) {
> > + qemu_put_be32s(f, &port->iov_idx);
> > + qemu_put_be64s(f, &port->iov_offset);
> >
> > - qemu_put_buffer(f, (unsigned char *)&port->elem,
> > - sizeof(port->elem));
> > + qemu_put_buffer(f, (unsigned char *)&port->elem,
> > + sizeof(port->elem));
> > + }
> > }
> > }
> > }
> > @@ -816,6 +863,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
> > VirtIOSerial *vser;
> > VirtIODevice *vdev;
> > uint32_t i, max_supported_ports;
> > + unsigned int savevm_ver;
> >
> > if (!conf->max_virtserial_ports)
> > return NULL;
> > @@ -881,11 +929,18 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
> >
> > vser->qdev = dev;
> >
> > + vser->flow_control = true;
> > + savevm_ver = 3;
> > + if (!conf->flow_control) {
> > + vser->flow_control = false;
> > + savevm_ver = 2;
> > + }
> > +
> > /*
> > * Register for the savevm section with the virtio-console name
> > * to preserve backward compat
> > */
> > - register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
> > + register_savevm(dev, "virtio-console", -1, savevm_ver, virtio_serial_save,
> > virtio_serial_load, vser);
> >
> > return vdev;
> > diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
> > index de624c3..57d2dee 100644
> > --- a/hw/virtio-serial.h
> > +++ b/hw/virtio-serial.h
> > @@ -48,6 +48,13 @@ struct virtio_console_control {
> > struct virtio_serial_conf {
> > /* Max. number of ports we can have for a the virtio-serial device */
> > uint32_t max_virtserial_ports;
> > +
> > + /*
> > + * Should this device behave the way it did in prior to pc-0.14
> > + * (ie. no flow control)? This will be necessary to allow
> > + * migrations from a pre-0.14-machine type to older qemu code
> > + */
> > + uint32_t flow_control;
> > };
> >
> > /* Some events for the internal messages (control packets) */
> > @@ -204,4 +211,9 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
> > */
> > void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
> >
> > +/*
> > + * Does this machine type disable the use of flow control?
> > + */
> > +bool virtio_serial_flow_control_enabled(VirtIOSerialPort *port);
> > +
> > #endif
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-02-07 16:11 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-03 6:17 [Qemu-devel] [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy Amit Shah
2011-02-03 6:17 ` [Qemu-devel] [PATCH master/0.14 2/2] virtio-serial: Add older machine compat property for flow control Amit Shah
2011-02-07 15:47 ` [Qemu-devel] " Alex Williamson
2011-02-07 16:10 ` Michael S. Tsirkin
2011-02-07 15:46 ` [Qemu-devel] Re: [PATCH master/0.14 1/2] virtio-serial: Use a struct to pass config information from proxy Alex Williamson
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).