Skip to contentSkip to conversation

Multiple QEMU AIO implementations

RFC In review Anthony Liguori 2 participants 2 messages Apr 16, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 Multiple QEMU AIO implementations

This isn't fully cooked yet, but pretty close. The basic idea is to make the aio usage in block-raw go to a set of function pointers and allow multiple simultaneous AIO implementations.

I converted the posix-aio support to this, and also introduced a "unix" aio which just uses O_NONBLOCK and select(). The later only supports 1 simultaneous request per-fd but currently posix-aio is limited to that too. At least with my QEMU testing, the unix aio implementation outperforms posix-aio by a factor of 2.

And it uses no signals...

I'm inclined to suggest that we use signalfd with posix-aio, and for older guests, just fall back to unix aio. We can also introduce a linux-aio and use that when possible.

Regards,

Anthony Liguori

Makefile +1 -1
index a8df278..916f071 100644
@@ -139,7 +139,7 @@ QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS)
 ifdef CONFIG_WIN32
 QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o
 else
-QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o
+QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o qemu-img-aio-posix.o
 endif
 
 ######################################################################
Makefile.target +1 -1
index 75de753..773e81d 100644
@@ -485,7 +485,7 @@ OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o
 ifdef CONFIG_WIN32
 OBJS+=block-raw-win32.o
 else
-OBJS+=block-raw-posix.o
+OBJS+=block-raw-posix.o aio-posix.o aio-unix.o
 endif
 
 LIBS+=-lz
aio-posix.c new file +291 -0

291 lines not on this page · raw message

aio-unix.c new file +208 -0

208 lines not on this page · raw message

block-aio.h new file +34 -0
new file mode 100644
index 0000000..30c279a
@@ -0,0 +1,34 @@
+#ifndef QEMU_AIO_H
+#define QEMU_AIO_H
+
+#include "qemu-common.h"
+#include "block.h"
+
+typedef struct AIODriver
+{
+    const char *name;
+    size_t aiocb_size;
+    void (*aio_init)(void);
+    void (*aio_wait_start)(void);
+    void (*aio_wait)(void);
+    void (*aio_wait_end)(void);
+    void (*aio_flush)(void);
+    BlockDriverAIOCB *(*aio_submit)(BlockDriverState *bs, int fd,
+				    int64_t sector_num, void *buf,
+				    int sectors, int write,
+				    BlockDriverCompletionFunc *cb,
+				    void *opaque);
+    void (*aio_cancel)(BlockDriverAIOCB *aiocb);
+    struct AIODriver *next;
+} AIODriver;
+
+int qemu_register_aio(AIODriver *drv);
+
+int qemu_set_aio_driver(const char *name);
+
+extern AIODriver *aio_drv;
+
+int posix_aio_init(void);
+int unix_aio_init(void);
+
+#endif
block-raw-posix.c +31 -186

289 lines not on this page · raw message

block-raw-win32.c +0 -4
index 43d3f6c..6b40a27 100644
@@ -350,10 +350,6 @@ void qemu_aio_init(void)
 {
 }
 
-void qemu_aio_poll(void)
-{
-}
-
 void qemu_aio_flush(void)
 {
 }
block.c +39 -0
index eb610e0..b6e4bd4 100644
@@ -26,6 +26,7 @@
 #include "console.h"
 #endif
 #include "block_int.h"
+#include "block-aio.h"
 
 #ifdef _BSD
 #include <sys/types.h>
@@ -1347,6 +1348,10 @@ void bdrv_init(void)
     bdrv_register(&bdrv_vvfat);
     bdrv_register(&bdrv_qcow2);
     bdrv_register(&bdrv_parallels);
+#ifndef QEMU_IMG
+    unix_aio_init();
+#endif
+    posix_aio_init();
 }
 
 void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
@@ -1378,6 +1383,40 @@ void qemu_aio_release(void *p)
     drv->free_aiocb = acb;
 }
 
+static AIODriver *aio_driver_list;
+AIODriver *aio_drv;
+
+int qemu_register_aio(AIODriver *drv)
+{
+    drv->next = aio_driver_list;
+    aio_driver_list = drv;
+    aio_drv = aio_driver_list;
+
+    return 0;
+}
+
+int qemu_set_aio_driver(const char *name)
+{
+    AIODriver *drv;
+
+    if (!strcmp(name, "?")) {
+	printf("Available aio drivers:\n");
+	for (drv = aio_driver_list; drv; drv = drv->next) {
+	    printf("%s\n", drv->name);
+	}
+	exit(0);
+    }
+
+    for (drv = aio_driver_list; drv; drv = drv->next) {
+	if (!strcmp(name, drv->name))
+	    break;
+    }
+
+    aio_drv = drv;
+
+    return 0;
+}
+
 /**************************************************************/
 /* removable device support */
 
block.h +0 -1
index 9d30db2..ff19425 100644
@@ -94,7 +94,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
 void bdrv_aio_cancel(BlockDriverAIOCB *acb);
 
 void qemu_aio_init(void);
-void qemu_aio_poll(void);
 void qemu_aio_flush(void);
 void qemu_aio_wait_start(void);
 void qemu_aio_wait(void);
sysemu.h +2 -0
index 0078190..9931139 100644
@@ -41,6 +41,8 @@ void qemu_system_powerdown(void);
 #endif
 void qemu_system_reset(void);
 
+void qemu_register_poll(IOHandler *poll, void *opaque);
+
 void cpu_save(QEMUFile *f, void *opaque);
 int cpu_load(QEMUFile *f, void *opaque, int version_id);
 
vl.c +45 -2

107 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#1 lore raw
Quoted 3 lines · Anthony Liguori

This isn't fully cooked yet, but pretty close. The basic idea is to make the aio usage in block-raw go to a set of function pointers and allow multiple simultaneous AIO implementations.

The AIO API looks great. Looking forward to a linux-aio backend.

Quoted 5 lines

I converted the posix-aio support to this, and also introduced a "unix" aio which just uses O_NONBLOCK and select(). The later only supports 1 simultaneous request per-fd but currently posix-aio is limited to that too. At least with my QEMU testing, the unix aio implementation outperforms posix-aio by a factor of 2.

Unfortunately O_NONBLOCK is not honoured for block backed storage, so its a no-go.

Quoted 5 lines

And it uses no signals...

I'm inclined to suggest that we use signalfd with posix-aio, and for older guests, just fall back to unix aio. We can also introduce a linux-aio and use that when possible.

I think Avi's suggestion to emulate signalfd with a separate thread which does sigtimedwait+write-to-a-pipe is sensate.

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone