# We may submit more requests to the host than it is prepared to # handle. In this case, io_submit returns -EAGAIN. When this # happens, we return from submit_aio and sleep on the eagain_queue # wait_queue. We are woken from the interrupt handler - if some # requests have come back from the host, presumably there's some room # on the host to submit more requests. # # Interactions between this wait_queue and the sequence_queue and the # allocation semaphore - the sequence queue and any allocations always # happen first. While looping on this wait_queue, we do nothing but # try to resubmit to the host. Index: test/arch/um/drivers/ubd_kern.c =================================================================== --- test.orig/arch/um/drivers/ubd_kern.c 2005-09-17 17:40:53.000000000 -0400 +++ test/arch/um/drivers/ubd_kern.c 2005-09-17 17:41:03.000000000 -0400 @@ -574,6 +574,9 @@ static int ubd_reply_fd = -1; +DECLARE_WAIT_QUEUE_HEAD(eagain_queue); +static int dequeued; + static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused) { struct aio_thread_reply reply; @@ -629,6 +632,9 @@ } reactivate_fd(fd, UBD_IRQ); + dequeued = 1; + wake_up(&eagain_queue); + return(IRQ_HANDLED); } @@ -1376,7 +1382,19 @@ if(aio->bitmap != NULL) atomic_inc(&aio->bitmap->count); - err = submit_aio(&aio->aio); + while(1){ + unsigned long flags; + + err = submit_aio(&aio->aio); + if(err != -EAGAIN) + break; + dequeued = 0; + local_save_flags(flags); + local_irq_enable(); + wait_event(eagain_queue, dequeued); + local_irq_restore(flags); + } + if(err){ printk("do_io - submit_aio failed, " "err = %d\n", err); Index: test/arch/um/os-Linux/aio.c =================================================================== --- test.orig/arch/um/os-Linux/aio.c 2005-09-17 17:39:33.000000000 -0400 +++ test/arch/um/os-Linux/aio.c 2005-09-17 17:41:03.000000000 -0400 @@ -296,6 +296,9 @@ int err; err = do_aio(ctx, aio); + if(err == -EAGAIN) + return err; + if(err){ reply = ((struct aio_thread_reply) { .data = aio, .err = err });