Attached is my current set of I/O patches. It's significantly different, and simpler, than my previous set. Now, there is no sleeping while running the queue, so the spinlock is never dropped, and all of the extra synchronization is gone. do_ubd_handler runs the queue until it's empty, or the host refuses to take any more AIO requests. If the queue not empty, then the current state of the in-process request (the request itself and which sg entries have not yet been sent to the host) is saved in the device structure. When the interrupt handler empties out the host some, it will take the queue lock and call the request handler to push some more requests to the host. I also made the queues and locks per-device rather than having one for all devices. This means that when a device gets -EAGAIN from the host, the interrupt handler needs to know which queues got stalled. This is handled by having the request handler stick the device on a list when this happems, and the interrupt handler walks that list when rerunning request handlers. The patch name is the same as before, and now quite misleading because the queue lock is now not dropped. ubd-atomic is much the same as before, except simple flags is used to indicate whether the static buffers are available. This is OK since any reading or writing of the flags happens under the queue spinlock. init_aio_err is a simple error path cleanup patch. aio-batching causes the AIO thread not to process completions until the current batch of I/O is submitted. I added this because I was seeing a context switch between UML and the AIO thread on every AIO submission. This keeps the AIO thread asleep until the current I/O is fully submitted and it may be able to process a bunch of completions at once. o_direct adds O_DIRECT support to UML and makes the ubd driver use it. aio-errors makes submit_aio_24 return -errno instead of -1. I've given this a bunch of testing and it has survived overnight kernel build loops on both x86 and x86_64. The attached patches are against 2.6.14-rc2. Jeff