summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-09-29 01:27:59 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-09-29 01:27:59 -0400
commit6b175a022496572416918bd38d083120c23ba5f2 (patch)
tree049bc2743247c6d2bf6d97eec1b3325fef24cd4c
parent5e215654da7e97a6395de6e7592fbaa426697897 (diff)
Handle -EAGAIN from io_submit()
If io_submit() returns -EAGAIN, that just means the io context is full and we need to wait for completions - no need to die. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--linux/blkdev.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/linux/blkdev.c b/linux/blkdev.c
index 54af9f8..5cac6eb 100644
--- a/linux/blkdev.c
+++ b/linux/blkdev.c
@@ -289,6 +289,8 @@ static void sync_write(struct bio *bio, struct iovec * iov, unsigned i)
sync_check(bio, ret);
}
+static DECLARE_WAIT_QUEUE_HEAD(aio_events_completed);
+
static int aio_completion_thread(void *arg)
{
struct io_event events[8], *ev;
@@ -303,6 +305,8 @@ static int aio_completion_thread(void *arg)
continue;
if (ret < 0)
die("io_getevents() error: %s", strerror(-ret));
+ if (ret)
+ wake_up(&aio_events_completed);
for (ev = events; ev < events + ret; ev++) {
struct bio *bio = (struct bio *) ev->data;
@@ -394,7 +398,10 @@ static void aio_op(struct bio *bio, struct iovec *iov, unsigned i, int opcode)
}, *iocbp = &iocb;
atomic_inc(&running_requests);
- ret = io_submit(aio_ctx, 1, &iocbp);
+
+ wait_event(aio_events_completed,
+ (ret = io_submit(aio_ctx, 1, &iocbp)) != -EAGAIN);;
+
if (ret != 1)
die("io_submit err: %s", strerror(-ret));
}