ddf19c
From 38282d996cde61261211160577b366b83cad8012 Mon Sep 17 00:00:00 2001
ddf19c
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
ddf19c
Date: Mon, 27 Jan 2020 19:01:00 +0100
ddf19c
Subject: [PATCH 029/116] virtiofsd: Start queue threads
ddf19c
MIME-Version: 1.0
ddf19c
Content-Type: text/plain; charset=UTF-8
ddf19c
Content-Transfer-Encoding: 8bit
ddf19c
ddf19c
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
ddf19c
Message-id: <20200127190227.40942-26-dgilbert@redhat.com>
ddf19c
Patchwork-id: 93479
ddf19c
O-Subject: [RHEL-AV-8.2 qemu-kvm PATCH 025/112] virtiofsd: Start queue threads
ddf19c
Bugzilla: 1694164
ddf19c
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
ddf19c
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ddf19c
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
ddf19c
ddf19c
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
ddf19c
ddf19c
Start a thread for each queue when we get notified it's been started.
ddf19c
ddf19c
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
ddf19c
fix by:
ddf19c
Signed-off-by: Jun Piao <piaojun@huawei.com>
ddf19c
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
ddf19c
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
ddf19c
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
ddf19c
(cherry picked from commit e4c55a3c144493b436e40031e2eed61a84eca47b)
ddf19c
ddf19c
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ddf19c
---
ddf19c
 tools/virtiofsd/fuse_virtio.c | 89 +++++++++++++++++++++++++++++++++++++++++++
ddf19c
 1 file changed, 89 insertions(+)
ddf19c
ddf19c
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
ddf19c
index 4819e56..2a94bb3 100644
ddf19c
--- a/tools/virtiofsd/fuse_virtio.c
ddf19c
+++ b/tools/virtiofsd/fuse_virtio.c
ddf19c
@@ -11,6 +11,7 @@
ddf19c
  * See the file COPYING.LIB
ddf19c
  */
ddf19c
 
ddf19c
+#include "qemu/osdep.h"
ddf19c
 #include "fuse_virtio.h"
ddf19c
 #include "fuse_i.h"
ddf19c
 #include "standard-headers/linux/fuse.h"
ddf19c
@@ -30,6 +31,15 @@
ddf19c
 
ddf19c
 #include "contrib/libvhost-user/libvhost-user.h"
ddf19c
 
ddf19c
+struct fv_QueueInfo {
ddf19c
+    pthread_t thread;
ddf19c
+    struct fv_VuDev *virtio_dev;
ddf19c
+
ddf19c
+    /* Our queue index, corresponds to array position */
ddf19c
+    int qidx;
ddf19c
+    int kick_fd;
ddf19c
+};
ddf19c
+
ddf19c
 /*
ddf19c
  * We pass the dev element into libvhost-user
ddf19c
  * and then use it to get back to the outer
ddf19c
@@ -38,6 +48,13 @@
ddf19c
 struct fv_VuDev {
ddf19c
     VuDev dev;
ddf19c
     struct fuse_session *se;
ddf19c
+
ddf19c
+    /*
ddf19c
+     * The following pair of fields are only accessed in the main
ddf19c
+     * virtio_loop
ddf19c
+     */
ddf19c
+    size_t nqueues;
ddf19c
+    struct fv_QueueInfo **qi;
ddf19c
 };
ddf19c
 
ddf19c
 /* From spec */
ddf19c
@@ -83,6 +100,75 @@ static void fv_panic(VuDev *dev, const char *err)
ddf19c
     exit(EXIT_FAILURE);
ddf19c
 }
ddf19c
 
ddf19c
+static void *fv_queue_thread(void *opaque)
ddf19c
+{
ddf19c
+    struct fv_QueueInfo *qi = opaque;
ddf19c
+    fuse_log(FUSE_LOG_INFO, "%s: Start for queue %d kick_fd %d\n", __func__,
ddf19c
+             qi->qidx, qi->kick_fd);
ddf19c
+    while (1) {
ddf19c
+        /* TODO */
ddf19c
+    }
ddf19c
+
ddf19c
+    return NULL;
ddf19c
+}
ddf19c
+
ddf19c
+/* Callback from libvhost-user on start or stop of a queue */
ddf19c
+static void fv_queue_set_started(VuDev *dev, int qidx, bool started)
ddf19c
+{
ddf19c
+    struct fv_VuDev *vud = container_of(dev, struct fv_VuDev, dev);
ddf19c
+    struct fv_QueueInfo *ourqi;
ddf19c
+
ddf19c
+    fuse_log(FUSE_LOG_INFO, "%s: qidx=%d started=%d\n", __func__, qidx,
ddf19c
+             started);
ddf19c
+    assert(qidx >= 0);
ddf19c
+
ddf19c
+    /*
ddf19c
+     * Ignore additional request queues for now.  passthrough_ll.c must be
ddf19c
+     * audited for thread-safety issues first.  It was written with a
ddf19c
+     * well-behaved client in mind and may not protect against all types of
ddf19c
+     * races yet.
ddf19c
+     */
ddf19c
+    if (qidx > 1) {
ddf19c
+        fuse_log(FUSE_LOG_ERR,
ddf19c
+                 "%s: multiple request queues not yet implemented, please only "
ddf19c
+                 "configure 1 request queue\n",
ddf19c
+                 __func__);
ddf19c
+        exit(EXIT_FAILURE);
ddf19c
+    }
ddf19c
+
ddf19c
+    if (started) {
ddf19c
+        /* Fire up a thread to watch this queue */
ddf19c
+        if (qidx >= vud->nqueues) {
ddf19c
+            vud->qi = realloc(vud->qi, (qidx + 1) * sizeof(vud->qi[0]));
ddf19c
+            assert(vud->qi);
ddf19c
+            memset(vud->qi + vud->nqueues, 0,
ddf19c
+                   sizeof(vud->qi[0]) * (1 + (qidx - vud->nqueues)));
ddf19c
+            vud->nqueues = qidx + 1;
ddf19c
+        }
ddf19c
+        if (!vud->qi[qidx]) {
ddf19c
+            vud->qi[qidx] = calloc(sizeof(struct fv_QueueInfo), 1);
ddf19c
+            assert(vud->qi[qidx]);
ddf19c
+            vud->qi[qidx]->virtio_dev = vud;
ddf19c
+            vud->qi[qidx]->qidx = qidx;
ddf19c
+        } else {
ddf19c
+            /* Shouldn't have been started */
ddf19c
+            assert(vud->qi[qidx]->kick_fd == -1);
ddf19c
+        }
ddf19c
+        ourqi = vud->qi[qidx];
ddf19c
+        ourqi->kick_fd = dev->vq[qidx].kick_fd;
ddf19c
+        if (pthread_create(&ourqi->thread, NULL, fv_queue_thread, ourqi)) {
ddf19c
+            fuse_log(FUSE_LOG_ERR, "%s: Failed to create thread for queue %d\n",
ddf19c
+                     __func__, qidx);
ddf19c
+            assert(0);
ddf19c
+        }
ddf19c
+    } else {
ddf19c
+        /* TODO: Kill the thread */
ddf19c
+        assert(qidx < vud->nqueues);
ddf19c
+        ourqi = vud->qi[qidx];
ddf19c
+        ourqi->kick_fd = -1;
ddf19c
+    }
ddf19c
+}
ddf19c
+
ddf19c
 static bool fv_queue_order(VuDev *dev, int qidx)
ddf19c
 {
ddf19c
     return false;
ddf19c
@@ -92,6 +178,9 @@ static const VuDevIface fv_iface = {
ddf19c
     .get_features = fv_get_features,
ddf19c
     .set_features = fv_set_features,
ddf19c
 
ddf19c
+    /* Don't need process message, we've not got any at vhost-user level */
ddf19c
+    .queue_set_started = fv_queue_set_started,
ddf19c
+
ddf19c
     .queue_is_processed_in_order = fv_queue_order,
ddf19c
 };
ddf19c
 
ddf19c
-- 
ddf19c
1.8.3.1
ddf19c