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);