From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43748) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1blycQ-0006eq-UC for qemu-devel@nongnu.org; Mon, 19 Sep 2016 09:28:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1blycM-0005CL-8X for qemu-devel@nongnu.org; Mon, 19 Sep 2016 09:28:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38050) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1blycM-0005By-2x for qemu-devel@nongnu.org; Mon, 19 Sep 2016 09:28:18 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9DADD72983 for ; Mon, 19 Sep 2016 13:28:17 +0000 (UTC) From: Stefan Hajnoczi Date: Mon, 19 Sep 2016 14:28:05 +0100 Message-Id: <1474291685-24226-4-git-send-email-stefanha@redhat.com> In-Reply-To: <1474291685-24226-1-git-send-email-stefanha@redhat.com> References: <1474291685-24226-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PATCH 3/3] virtio-serial: add missing virtio_detach_element() call List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , lprosek@redhat.com, Stefan Hajnoczi , amit.shah@redhat.com Ports enter a "throttled" state when writing to the chardev would block. The current output VirtQueueElement is kept around until the chardev becomes writable again. There are several places in the virtio-serial lifecycle where the VirtQueueElement should be thrown away. For example, if the virtio device is reset then virtqueue elements are no longer valid. This patch adds the discard_throttle_data() function to unmap the scatter-gather list and decrement vq->inuse. This ensures that the VirtQueueElement is freed properly. Cc: amit.shah@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/char/virtio-serial-bus.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index db57a38..35aa3c7 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -132,6 +132,15 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev) virtio_notify(vdev, vq); } +static void discard_throttle_data(VirtIOSerialPort *port) +{ + if (port->elem) { + virtqueue_detach_element(port->ovq, port->elem, 0); + g_free(port->elem); + port->elem = NULL; + } +} + static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq, VirtIODevice *vdev) { @@ -254,6 +263,7 @@ int virtio_serial_close(VirtIOSerialPort *port) * consume, reset the throttling flag and discard the data. */ port->throttled = false; + discard_throttle_data(port); discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser)); send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 0); @@ -554,6 +564,9 @@ static void guest_reset(VirtIOSerial *vser) QTAILQ_FOREACH(port, &vser->ports, next) { vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); + + discard_throttle_data(port); + if (port->guest_connected) { port->guest_connected = false; if (vsc->set_guest_connected) { @@ -864,6 +877,7 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id) assert(port); /* Flush out any unconsumed buffers first */ + discard_throttle_data(port); discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser)); send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1); -- 2.7.4