Multiple QEMU AIO implementations
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
@@ -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
@@ -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
@@ -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
@@ -350,10 +350,6 @@ void qemu_aio_init(void) { } -void qemu_aio_poll (void ) -{ -} -void qemu_aio_flush (void ) { }
block.c +39 -0
@@ -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
@@ -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
@@ -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
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_NONBLOCKandselect(). 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