Messages in this thread Patch in this message | | | Subject | [PATCH 2.7.72-mm1] aio wait on io_queue_wait() | From | Daniel McNeil <> | Date | 19 Jun 2003 16:09:49 -0700 |
| |
I've been testing AIO on 2.5.72-mm1. While running tests using the io_submit(), io_queue_run() and io_queue_wait() interfaces, I noticed that io_queue_wait() was never waiting. It was always returning immediately. The library implements io_queue_wait(ctx, timeout) as io_getevents(ctx, 0, 0, NULL, timeout);
io_getevents() was always returning immediately since this is asking for zero events. Here's a patch that allows io_getevents() to wait for the timeout in this case. I changed aio_read_evt() to return if there are any events, but not the events themselves and changed read_events() to wait when there are no events.
I've tested this on my 2-proc.
Thoughts?
Daniel McNeil <daniel@osdl.org>
diff -rupN -X /home/daniel_nfs/dontdiff linux-2.5.72-mm1/fs/aio.c linux-2.5.72-mm1.aio/fs/aio.c --- linux-2.5.72-mm1/fs/aio.c 2003-06-19 15:35:38.763726959 -0700 +++ linux-2.5.72-mm1.aio/fs/aio.c 2003-06-19 15:29:50.448560742 -0700 @@ -956,6 +956,9 @@ int aio_complete(struct kiocb *iocb, lon * events fetched (0 or 1 ;-) * FIXME: make this use cmpxchg. * TODO: make the ringbuffer user mmap()able (requires FIXME). + * + * If ent is NULL, then only check if an event is on the ring. + * This is to handle io_queue_wait(). */ static int aio_read_evt(struct kioctx *ioctx, struct io_event *ent) { @@ -972,6 +975,15 @@ static int aio_read_evt(struct kioctx *i if (ring->head == ring->tail) goto out; + /* + * If ent == NULL we are just checking, + * so return now saying there is an event. + */ + if (ent == NULL) { + ret = 1; + goto out; + } + spin_lock(&info->ring_lock); head = ring->head % info->nr; @@ -1080,7 +1092,10 @@ static int read_events(struct kioctx *ct i ++; } - if (min_nr <= i) + /* + * To handle io_queue_wait(), do not return if nr and min_nr are zero. + */ + if (nr && min_nr && min_nr <= i) return i; if (ret) return ret; @@ -1097,6 +1112,28 @@ static int read_events(struct kioctx *ct set_timeout(start_jiffies, &to, &ts); } + /* + * Handle io_queue_wait() by waiting for any completed events, + * but not getting them off the ring. + */ + if (nr == 0) { + add_wait_queue_exclusive(&ctx->wait, &wait); + set_task_state(tsk, TASK_INTERRUPTIBLE); + ret = aio_read_evt(ctx, 0); + /* + * If there are no events and i/o active, wait. + */ + if (!ret && !to.timed_out && ctx->reqs_active) { + schedule(); + } + set_task_state(tsk, TASK_RUNNING); + remove_wait_queue(&ctx->wait, &wait); + if (timeout) + clear_timeout(&to); + return 0; + } + + while (likely(i < nr)) { add_wait_queue_exclusive(&ctx->wait, &wait); do { | |