From patchwork Thu Mar 19 07:35:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Shah X-Patchwork-Id: 451764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 84D0A140083 for ; Thu, 19 Mar 2015 18:36:46 +1100 (AEDT) Received: from localhost ([::1]:37524 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YYV0W-0004BZ-Hq for incoming@patchwork.ozlabs.org; Thu, 19 Mar 2015 03:36:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36553) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YYV03-0003Nh-A5 for qemu-devel@nongnu.org; Thu, 19 Mar 2015 03:36:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YYUzz-0001vO-AK for qemu-devel@nongnu.org; Thu, 19 Mar 2015 03:36:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44677) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YYUzz-0001v6-3j for qemu-devel@nongnu.org; Thu, 19 Mar 2015 03:36:11 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2J7a8rj016329 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 19 Mar 2015 03:36:08 -0400 Received: from localhost (dhcp193-78.pnq.redhat.com [10.65.193.78]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2J7a63X027349; Thu, 19 Mar 2015 03:36:07 -0400 From: Amit Shah To: qemu list Date: Thu, 19 Mar 2015 13:05:54 +0530 Message-Id: <8026596da2c98f4089c41f726354b91d557ee1fa.1426750554.git.amit.shah@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Peter Maydell , Markus Armbruster , Gerd Hoffmann , Amit Shah , marcandre.lureau@redhat.com, akong@redhat.com Subject: [Qemu-devel] [PATCH 1/1] virtio: serial: expose a 'guest_writable' callback for users X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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. Signed-off-by: Amit Shah Reviewed-by: Markus Armbruster --- Well I forgot to send this out for 2.3; I was waiting for the window to open, and totally forgot about it when it was open. Since this adds an internal API, and there's no chance of regressions, I propose we include this in 2.3. v4: fixed tabs in indentation (kraxel) v3: document the semantics of the callback (Peter Maydell, Markus) v2: check for port != NULL (Peter Maydell) --- hw/char/virtio-serial-bus.c | 31 +++++++++++++++++++++++++++++++ include/hw/virtio/virtio-serial.h | 11 +++++++++++ 2 files changed, 42 insertions(+) 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) diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index ccf8459..a275199 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -60,6 +60,17 @@ typedef struct VirtIOSerialPortClass { /* Guest is now ready to accept data (virtqueues set up). */ void (*guest_ready)(VirtIOSerialPort *port); + /* + * Guest has enqueued a buffer for the host to write into. + * Called each time a buffer is enqueued by the guest; + * irrespective of whether there already were free buffers the + * host could have consumed. + * + * This is dependent on both, the guest and host ends being + * connected. + */ + void (*guest_writable)(VirtIOSerialPort *port); + /* * Guest wrote some data to the port. This data is handed over to * the app via this callback. The app can return a size less than