Index: test/arch/um/drivers/ubd_kern.c =================================================================== --- test.orig/arch/um/drivers/ubd_kern.c 2005-09-27 12:02:19.000000000 -0400 +++ test/arch/um/drivers/ubd_kern.c 2005-09-27 12:03:00.000000000 -0400 @@ -1081,7 +1081,7 @@ if(dev->end_sg == 0){ struct request *req = elv_next_request(q); if(req == NULL) - return; + goto out; dev->request = req; blkdev_dequeue_request(req); @@ -1103,7 +1103,7 @@ if(do_io(&io_req, req, dev->cow.bitmap) == -EAGAIN){ if(list_empty(&dev->restart)) list_add(&dev->restart, &restart); - return; + goto out; } req->sector += sg->length >> 9; @@ -1112,6 +1112,8 @@ dev->end_sg = 0; dev->request = NULL; } +out: + finish_aio(); } static int ubd_ioctl(struct inode * inode, struct file * file, Index: test/arch/um/include/aio.h =================================================================== --- test.orig/arch/um/include/aio.h 2005-09-27 11:33:43.000000000 -0400 +++ test/arch/um/include/aio.h 2005-09-27 12:03:00.000000000 -0400 @@ -36,5 +36,6 @@ .next = NULL } extern int submit_aio(struct aio_context *aio); +extern int finish_aio(void); #endif Index: test/arch/um/os-Linux/aio.c =================================================================== --- test.orig/arch/um/os-Linux/aio.c 2005-09-27 12:02:42.000000000 -0400 +++ test/arch/um/os-Linux/aio.c 2005-09-27 12:03:00.000000000 -0400 @@ -80,6 +80,9 @@ * that it now backs the mmapped area. */ +/* XXX Fix for SMP */ +static int pending_events; + static int do_aio(aio_context_t ctx, struct aio_context *aio) { struct iocb iocb, *iocbp = &iocb; @@ -115,8 +118,10 @@ } err = io_submit(ctx, 1, &iocbp); - if(err > 0) + if(err > 0){ err = 0; + pending_events++; + } else err = -errno; @@ -124,6 +129,21 @@ return err; } +static int aio_wakeup_r_fd; +static int aio_wakeup_w_fd; + +static int finish_aio_26(void) +{ + int err; + + err = write(aio_wakeup_w_fd, &pending_events, sizeof(pending_events)); + err = (err != sizeof(pending_events)) ? errno : 0; + + pending_events = 0; + + return err; +} + static aio_context_t ctx = 0; static int aio_thread(void *arg) @@ -131,35 +151,44 @@ struct aio_thread_reply reply; struct aio_context *aio; struct io_event event; - int err, n; + int err, i, n, nevents; signal(SIGWINCH, SIG_IGN); while(1){ - n = io_getevents(ctx, 1, 1, &event, NULL); - if(n < 0){ - if(errno == EINTR) - continue; - printk("aio_thread - io_getevents failed, " - "errno = %d\n", errno); - } - else { - aio = (struct aio_context *) (long) event.data; - if(update_aio(aio, event.res)){ - do_aio(ctx, aio); - continue; + n = read(aio_wakeup_r_fd, &nevents, sizeof(nevents)); + if(n != sizeof(nevents)){ + printk("aio_thread - reading wakeup fd returned " + "%d, errno = %d\n", n, errno); + continue; + } + + for(i = 0; i < nevents; i++){ + n = io_getevents(ctx, 1, 1, &event, NULL); + if(n < 0){ + if(errno == EINTR) + continue; + printk("aio_thread - io_getevents failed, " + "errno = %d\n", errno); } - - reply = ((struct aio_thread_reply) - { .data = aio, - .err = aio->len }); - err = os_write_file(aio->reply_fd, &reply, - sizeof(reply)); - if(err != sizeof(reply)) - printk("aio_thread - write failed, " - "fd = %d, err = %d\n", aio->reply_fd, - -err); - } + else { + aio = (struct aio_context *) (long) event.data; + if(update_aio(aio, event.res)){ + do_aio(ctx, aio); + continue; + } + + reply = ((struct aio_thread_reply) + { .data = aio, + .err = aio->len }); + err = os_write_file(aio->reply_fd, &reply, + sizeof(reply)); + if(err != sizeof(reply)) + printk("aio_thread - write failed, " + "fd = %d, err = %d\n", + aio->reply_fd, -err); + } + } } return 0; } @@ -251,6 +280,7 @@ static int aio_pid = -1; static int (*submit_proc)(struct aio_context *aio); +static int (*finish_proc)(void); static int init_aio_24(void) { @@ -315,7 +345,7 @@ static int init_aio_26(void) { unsigned long stack; - int err; + int err, wakeup_pipe[2]; if(io_setup(256, &ctx)){ err = -errno; @@ -324,10 +354,18 @@ goto out; } + if(pipe(wakeup_pipe) < 0){ + err = -errno; + goto out; + } + + aio_wakeup_r_fd = wakeup_pipe[0]; + aio_wakeup_w_fd = wakeup_pipe[1]; + err = run_helper_thread(aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); if(err < 0) - goto out; + goto out_close; aio_pid = err; err = 0; @@ -335,9 +373,15 @@ printk("Using 2.6 host AIO\n"); submit_proc = submit_aio_26; + finish_proc = finish_aio_26; out: return err; + +out_close: + close(wakeup_pipe[0]); + close(wakeup_pipe[1]); + goto out; } #else @@ -350,6 +394,7 @@ static int init_aio_26(void) { submit_proc = submit_aio_26; + finish_proc = finish_aio_26; return -ENOSYS; } #endif @@ -420,3 +465,11 @@ { return (*submit_proc)(aio); } + +int finish_aio(void) +{ + if(finish_proc == NULL) + return 0; + + return (*finish_proc)(); +}