this moves writes into a thread. we need to do reads too, but the write side
is much easier... could use a little more testing.


Index: virtio.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/virtio.c,v
retrieving revision 1.49
diff -u -p -r1.49 virtio.c
--- virtio.c    30 May 2017 17:56:47 -0000      1.49
+++ virtio.c    10 Aug 2017 16:41:59 -0000
@@ -63,6 +63,7 @@ int nr_vioblk;
 #define VMMCI_F_SYNCRTC                (1<<2)
 
 struct ioinfo {
+       TAILQ_ENTRY(ioinfo) next;
        uint8_t *buf;
        ssize_t len;
        off_t offset;
@@ -70,6 +71,11 @@ struct ioinfo {
        int error;
 };
 
+static pthread_t iothread;
+static TAILQ_HEAD(, ioinfo) pending_ios;
+static pthread_mutex_t iomtx;
+static pthread_cond_t iocond;
+
 const char *
 vioblk_cmd_name(uint32_t type)
 {
@@ -415,6 +421,37 @@ vioblk_finish_write(struct ioinfo *info)
        return 0;
 }
 
+static void *
+vioblk_iowriter(void *v)
+{
+       struct ioinfo *info;
+
+       pthread_mutex_lock(&iomtx);
+       while (1) {
+               while ((info = TAILQ_FIRST(&pending_ios))) {
+                       TAILQ_REMOVE(&pending_ios, info, next);
+                       pthread_mutex_unlock(&iomtx);
+
+                       if (vioblk_finish_write(info))
+                               log_warnx("wr vioblk: disk write error");
+
+                       vioblk_free_info(info);
+                       pthread_mutex_lock(&iomtx);
+               }
+               pthread_cond_wait(&iocond, &iomtx);
+       }
+}
+
+void
+vioblk_writer_init(void)
+{
+       TAILQ_INIT(&pending_ios);
+       pthread_mutex_init(&iomtx, NULL);
+       pthread_cond_init(&iocond, NULL);
+       pthread_create(&iothread, NULL, vioblk_iowriter, NULL);
+
+}
+
 /*
  * XXX in various cases, ds should be set to VIRTIO_BLK_S_IOERR, if we can
  * XXX cant trust ring data from VM, be extra cautious.
@@ -592,14 +629,10 @@ vioblk_notifyq(struct vioblk_dev *dev)
                                        goto out;
                                }
 
-                               if (vioblk_finish_write(info)) {
-                                       log_warnx("wr vioblk: disk write "
-                                           "error");
-                                       vioblk_free_info(info);
-                                       goto out;
-                               }
-
-                               vioblk_free_info(info);
+                               pthread_mutex_lock(&iomtx);
+                               TAILQ_INSERT_TAIL(&pending_ios, info, next);
+                               pthread_cond_signal(&iocond);
+                               pthread_mutex_unlock(&iomtx);
 
                                secbias += secdata_desc->len /
                                    VIRTIO_BLK_SECTOR_SIZE;
Index: virtio.h
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/virtio.h,v
retrieving revision 1.19
diff -u -p -r1.19 virtio.h
--- virtio.h    20 Jun 2017 01:59:12 -0000      1.19
+++ virtio.h    10 Aug 2017 16:41:49 -0000
@@ -178,6 +178,7 @@ int vioblk_restore(int, struct vm_create
 void vioblk_update_qs(struct vioblk_dev *);
 void vioblk_update_qa(struct vioblk_dev *);
 int vioblk_notifyq(struct vioblk_dev *);
+void vioblk_writer_init(void);
 
 int virtio_net_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
 int vionet_dump(int);
Index: vm.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/vm.c,v
retrieving revision 1.22
diff -u -p -r1.22 vm.c
--- vm.c        15 Jul 2017 05:05:36 -0000      1.22
+++ vm.c        10 Aug 2017 16:41:53 -0000
@@ -1014,6 +1014,8 @@ run_vm(int *child_disks, int *child_taps
                return (ENOMEM);
        }
 
+       vioblk_writer_init();
+
        log_debug("%s: initializing hardware for vm %s", __func__,
            vcp->vcp_name);
 

Reply via email to