aboutsummaryrefslogtreecommitdiff
path: root/hw/char
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2014-07-17 20:02:45 +0530
committerAmit Shah <amit.shah@redhat.com>2015-03-19 17:35:40 +0530
commit4add73aa601ab42b7a9863d483fa313b06105b34 (patch)
tree9d181e5e777b8bea757911f2b31d70fe2192a1a9 /hw/char
parent17b11a1406fdc43b5022f32a6fbfcb005a353b38 (diff)
downloadqemu-4add73aa601ab42b7a9863d483fa313b06105b34.zip
qemu-4add73aa601ab42b7a9863d483fa313b06105b34.tar.gz
qemu-4add73aa601ab42b7a9863d483fa313b06105b34.tar.bz2
virtio: serial: expose a 'guest_writable' callback for users
Users of virtio-serial may want to know when a port becomes writable. A port can stop accepting writes if the guest port is open but not being read from. In this case, data gets queued up in the virtqueue, and after the vq is full, writes to the port do not succeed. When the guest reads off a vq element, and adds a new one for the host to put data in, we can tell users the port is available for more writes, via the new ->guest_writable() callback. Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Amit Shah <amit.shah@redhat.com>
Diffstat (limited to 'hw/char')
-rw-r--r--hw/char/virtio-serial-bus.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index c86814f..d14e872 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -465,6 +465,37 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
{
+ /*
+ * Users of virtio-serial would like to know when guest becomes
+ * writable again -- i.e. if a vq had stuff queued up and the
+ * guest wasn't reading at all, the host would not be able to
+ * write to the vq anymore. Once the guest reads off something,
+ * we can start queueing things up again. However, this call is
+ * made for each buffer addition by the guest -- even though free
+ * buffers existed prior to the current buffer addition. This is
+ * done so as not to maintain previous state, which will need
+ * additional live-migration-related changes.
+ */
+ VirtIOSerial *vser;
+ VirtIOSerialPort *port;
+ VirtIOSerialPortClass *vsc;
+
+ vser = VIRTIO_SERIAL(vdev);
+ port = find_port_by_vq(vser, vq);
+
+ if (!port) {
+ return;
+ }
+ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+
+ /*
+ * If guest_connected is false, this call is being made by the
+ * early-boot queueing up of descriptors, which is just noise for
+ * the host apps -- don't disturb them in that case.
+ */
+ if (port->guest_connected && port->host_connected && vsc->guest_writable) {
+ vsc->guest_writable(port);
+ }
}
static uint32_t get_features(VirtIODevice *vdev, uint32_t features)