From patchwork Fri Mar 18 17:01:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 8622531 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BF77C9F44D for ; Fri, 18 Mar 2016 17:18:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E189E2026F for ; Fri, 18 Mar 2016 17:18:48 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 159F02022A for ; Fri, 18 Mar 2016 17:18:48 +0000 (UTC) Received: from localhost ([::1]:45186 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agy2x-0006yR-CH for patchwork-qemu-devel@patchwork.kernel.org; Fri, 18 Mar 2016 13:18:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41901) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agxmN-0006ew-QR for qemu-devel@nongnu.org; Fri, 18 Mar 2016 13:01:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1agxmL-00088j-2K for qemu-devel@nongnu.org; Fri, 18 Mar 2016 13:01:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42963) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agxmK-00088D-Qp for qemu-devel@nongnu.org; Fri, 18 Mar 2016 13:01:36 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 63DB8811D2 for ; Fri, 18 Mar 2016 17:01:36 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-34.ams2.redhat.com [10.36.116.34]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u2IH1Wx5010095 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 18 Mar 2016 13:01:35 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id D6BDF3006AF4; Fri, 18 Mar 2016 18:01:28 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Fri, 18 Mar 2016 18:01:16 +0100 Message-Id: <1458320487-19603-30-git-send-email-armbru@redhat.com> In-Reply-To: <1458320487-19603-1-git-send-email-armbru@redhat.com> References: <1458320487-19603-1-git-send-email-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 29/40] ivshmem: Simplify how we cope with short reads from server 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Short reads from a UNIX domain sockets are exceedingly unlikely when the other side always sends eight bytes and we always read eight bytes. We cope with them anyway. However, the code doing that is rather convoluted. Dumb it down radically. Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Message-Id: <1458066895-20632-30-git-send-email-armbru@redhat.com> --- hw/misc/ivshmem.c | 75 ++++++++++++------------------------------------------- 1 file changed, 16 insertions(+), 59 deletions(-) diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index c1a75db..7b9e769 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -26,7 +26,6 @@ #include "migration/migration.h" #include "qemu/error-report.h" #include "qemu/event_notifier.h" -#include "qemu/fifo8.h" #include "sysemu/char.h" #include "sysemu/hostmem.h" #include "qapi/visitor.h" @@ -80,7 +79,6 @@ typedef struct IVShmemState { uint32_t intrstatus; CharDriverState *server_chr; - Fifo8 incoming_fifo; MemoryRegion ivshmem_mmio; /* We might need to register the BAR before we actually have the memory. @@ -99,6 +97,8 @@ typedef struct IVShmemState { uint32_t vectors; uint32_t features; MSIVector *msi_vectors; + uint64_t msg_buf; /* buffer for receiving server messages */ + int msg_buffered_bytes; /* #bytes in @msg_buf */ Error *migration_blocker; @@ -255,11 +255,6 @@ static const MemoryRegionOps ivshmem_mmio_ops = { }, }; -static int ivshmem_can_receive(void * opaque) -{ - return sizeof(int64_t); -} - static void ivshmem_vector_notify(void *opaque) { MSIVector *entry = opaque; @@ -459,53 +454,6 @@ static void resize_peers(IVShmemState *s, int nb_peers) } } -static bool fifo_update_and_get(IVShmemState *s, const uint8_t *buf, int size, - void *data, size_t len) -{ - const uint8_t *p; - uint32_t num; - - assert(len <= sizeof(int64_t)); /* limitation of the fifo */ - if (fifo8_is_empty(&s->incoming_fifo) && size == len) { - memcpy(data, buf, size); - return true; - } - - IVSHMEM_DPRINTF("short read of %d bytes\n", size); - - num = MIN(size, sizeof(int64_t) - fifo8_num_used(&s->incoming_fifo)); - fifo8_push_all(&s->incoming_fifo, buf, num); - - if (fifo8_num_used(&s->incoming_fifo) < len) { - assert(num == 0); - return false; - } - - size -= num; - buf += num; - p = fifo8_pop_buf(&s->incoming_fifo, len, &num); - assert(num == len); - - memcpy(data, p, len); - - if (size > 0) { - fifo8_push_all(&s->incoming_fifo, buf, size); - } - - return true; -} - -static bool fifo_update_and_get_i64(IVShmemState *s, - const uint8_t *buf, int size, int64_t *i64) -{ - if (fifo_update_and_get(s, buf, size, i64, sizeof(*i64))) { - *i64 = GINT64_FROM_LE(*i64); - return true; - } - - return false; -} - static void ivshmem_add_kvm_msi_virq(IVShmemState *s, int vector, Error **errp) { @@ -658,6 +606,14 @@ static void process_msg(IVShmemState *s, int64_t msg, int fd, Error **errp) } } +static int ivshmem_can_receive(void *opaque) +{ + IVShmemState *s = opaque; + + assert(s->msg_buffered_bytes < sizeof(s->msg_buf)); + return sizeof(s->msg_buf) - s->msg_buffered_bytes; +} + static void ivshmem_read(void *opaque, const uint8_t *buf, int size) { IVShmemState *s = opaque; @@ -665,9 +621,14 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) int fd; int64_t msg; - if (!fifo_update_and_get_i64(s, buf, size, &msg)) { + assert(size >= 0 && s->msg_buffered_bytes + size <= sizeof(s->msg_buf)); + memcpy((unsigned char *)&s->msg_buf + s->msg_buffered_bytes, buf, size); + s->msg_buffered_bytes += size; + if (s->msg_buffered_bytes < sizeof(s->msg_buf)) { return; } + msg = le64_to_cpu(s->msg_buf); + s->msg_buffered_bytes = 0; fd = qemu_chr_fe_get_msgfd(s->server_chr); IVSHMEM_DPRINTF("posn is %" PRId64 ", fd is %d\n", msg, fd); @@ -1022,8 +983,6 @@ static void pci_ivshmem_realize(PCIDevice *dev, Error **errp) } } - fifo8_create(&s->incoming_fifo, sizeof(int64_t)); - if (s->role_val == IVSHMEM_PEER) { error_setg(&s->migration_blocker, "Migration is disabled when using feature 'peer mode' in device 'ivshmem'"); @@ -1036,8 +995,6 @@ static void pci_ivshmem_exit(PCIDevice *dev) IVShmemState *s = IVSHMEM(dev); int i; - fifo8_destroy(&s->incoming_fifo); - if (s->migration_blocker) { migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker);