All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: claudio.fontana@huawei.com, cam@cs.ualberta.ca,
	mlureau@redhat.com, david.marchand@6wind.com,
	pbonzini@redhat.com
Subject: [Qemu-devel] [PATCH v2 31/42] ivshmem: Simplify how we cope with short reads from server
Date: Mon,  7 Mar 2016 20:25:43 +0100	[thread overview]
Message-ID: <1457378754-21649-32-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1457378754-21649-1-git-send-email-armbru@redhat.com>

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 <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 2b14daa..ef4249b 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);
@@ -1018,8 +979,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'");
@@ -1032,8 +991,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);
-- 
2.4.3

  parent reply	other threads:[~2016-03-07 19:26 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-07 19:25 [Qemu-devel] [PATCH v2 00/42] ivshmem: Fixes, cleanups, device model split Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 01/42] exec: Fix memory allocation when memory path names new file Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 02/42] exec: Fix memory allocation when memory path isn't on hugetlbfs Markus Armbruster
2016-03-08 14:17   ` Paolo Bonzini
2016-03-15 16:41     ` Markus Armbruster
2016-03-15 16:56       ` Paolo Bonzini
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 03/42] target-ppc: Document TOCTTOU in hugepage support Markus Armbruster
2016-03-09 12:44   ` Marc-André Lureau
2016-03-09 20:05     ` Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 04/42] ivshmem-server: Fix and clean up command line help Markus Armbruster
2016-03-09 12:44   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 05/42] ivshmem-server: Don't overload POSIX shmem and file name Markus Armbruster
2016-03-09 12:44   ` Marc-André Lureau
2016-03-09 20:14     ` Markus Armbruster
2016-03-10  0:44       ` Marc-André Lureau
2016-03-10  6:57         ` Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 06/42] qemu-doc: Fix ivshmem huge page example Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 07/42] event_notifier: Make event_notifier_init_fd() #ifdef CONFIG_EVENTFD Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 08/42] tests/libqos/pci-pc: Fix qpci_pc_iomap() to map BARs aligned Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 09/42] ivshmem-test: Improve test case /ivshmem/single Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 10/42] ivshmem-test: Clean up wait for devices to become operational Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 11/42] ivshmem-test: Improve test cases /ivshmem/server-* Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 12/42] ivshmem: Rewrite specification document Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 13/42] ivshmem: Add missing newlines to debug printfs Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 14/42] ivshmem: Compile debug prints unconditionally to prevent bit-rot Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 15/42] ivshmem: Clean up after commit 9940c32 Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 16/42] ivshmem: Drop ivshmem_event() stub Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 17/42] ivshmem: Don't destroy the chardev on version mismatch Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 18/42] ivshmem: Fix harmless misuse of Error Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 19/42] ivshmem: Failed realize() can leave migration blocker behind Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 20/42] ivshmem: Clean up register callbacks Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 21/42] ivshmem: Clean up MSI-X conditions Markus Armbruster
2016-03-09 12:45   ` Marc-André Lureau
2016-03-09 20:15     ` Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 22/42] ivshmem: Leave INTx alone when using MSI-X Markus Armbruster
2016-03-09 12:45   ` Marc-André Lureau
2016-03-09 20:16     ` Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 23/42] ivshmem: Assert interrupts are set up once Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 24/42] ivshmem: Simplify rejection of invalid peer ID from server Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 25/42] ivshmem: Disentangle ivshmem_read() Markus Armbruster
2016-03-09 12:45   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 26/42] ivshmem: Plug leaks on unplug, fix peer disconnect Markus Armbruster
2016-03-09 12:45   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 27/42] ivshmem: Receive shared memory synchronously in realize() Markus Armbruster
2016-03-09 12:45   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 28/42] ivshmem: Propagate errors through ivshmem_recv_setup() Markus Armbruster
2016-03-09 12:46   ` Marc-André Lureau
2016-03-09 20:25     ` Markus Armbruster
2016-03-10  0:44       ` Marc-André Lureau
2016-03-10  6:38         ` Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 29/42] ivshmem: Rely on server sending the ID right after the version Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 30/42] ivshmem: Drop the hackish test for UNIX domain chardev Markus Armbruster
2016-03-07 19:25 ` Markus Armbruster [this message]
2016-03-09 12:46   ` [Qemu-devel] [PATCH v2 31/42] ivshmem: Simplify how we cope with short reads from server Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 32/42] ivshmem: Tighten check of property "size" Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 33/42] ivshmem: Implement shm=... with a memory backend Markus Armbruster
2016-03-09 11:31   ` Marc-André Lureau
2016-03-09 20:59     ` Markus Armbruster
2016-03-10  0:44       ` Marc-André Lureau
2016-03-10  6:48         ` Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 34/42] ivshmem: Simplify memory regions for BAR 2 (shared memory) Markus Armbruster
2016-03-09 12:46   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 35/42] ivshmem: Inline check_shm_size() into its only caller Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 36/42] qdev: New DEFINE_PROP_ON_OFF_AUTO Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 37/42] ivshmem: Replace int role_val by OnOffAuto master Markus Armbruster
2016-03-09 12:46   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 38/42] ivshmem: Split ivshmem-plain, ivshmem-doorbell off ivshmem Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 39/42] ivshmem: Clean up after the previous commit Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 40/42] ivshmem: Drop ivshmem property x-memdev Markus Armbruster
2016-03-09 12:47   ` Marc-André Lureau
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 41/42] ivshmem: Require master to have ID zero Markus Armbruster
2016-03-07 19:25 ` [Qemu-devel] [PATCH v2 42/42] contrib/ivshmem-server: Print "not for production" warning Markus Armbruster
2016-03-08 14:05 ` [Qemu-devel] [PATCH v2 00/42] ivshmem: Fixes, cleanups, device model split Paolo Bonzini
2016-03-08 14:22 ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457378754-21649-32-git-send-email-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=cam@cs.ualberta.ca \
    --cc=claudio.fontana@huawei.com \
    --cc=david.marchand@6wind.com \
    --cc=mlureau@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.