aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>2019-04-04 14:20:47 +0100
committerWill Deacon <will.deacon@arm.com>2019-04-26 14:57:59 +0100
commit200cb82311bb79b18994b2bfbad6b090eee7f0d0 (patch)
tree40a45a87b513be79e0e5f0e28ba73ce73578c603
parentd62e8ee002eb1ef50d0ca9dfa4f0c04782e53879 (diff)
downloadkvmtool-200cb82311bb79b18994b2bfbad6b090eee7f0d0.tar.gz
disk/aio: Fix AIO thread
Currently when the kernel completes a batch of AIO requests and signals it via eventfd, we retrieve at most AIO_MAX events (256), and ignore the rest. Call io_getevents() again in case more events are pending. Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--disk/aio.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/disk/aio.c b/disk/aio.c
index 007415c6..1fcf3685 100644
--- a/disk/aio.c
+++ b/disk/aio.c
@@ -66,20 +66,31 @@ ssize_t raw_image__write_async(struct disk_image *disk, u64 sector,
offset, disk->evt, param);
}
-static void *disk_aio_thread(void *param)
+static int disk_aio_get_events(struct disk_image *disk)
{
- struct disk_image *disk = param;
struct io_event event[AIO_MAX];
struct timespec notime = {0};
int nr, i;
+
+ do {
+ nr = io_getevents(disk->ctx, 1, ARRAY_SIZE(event), event, &notime);
+ for (i = 0; i < nr; i++)
+ disk->disk_req_cb(event[i].data, event[i].res);
+ } while (nr > 0);
+
+ return 0;
+}
+
+static void *disk_aio_thread(void *param)
+{
+ struct disk_image *disk = param;
u64 dummy;
kvm__set_thread_name("disk-image-io");
while (read(disk->evt, &dummy, sizeof(dummy)) > 0) {
- nr = io_getevents(disk->ctx, 1, ARRAY_SIZE(event), event, &notime);
- for (i = 0; i < nr; i++)
- disk->disk_req_cb(event[i].data, event[i].res);
+ if (disk_aio_get_events(disk))
+ break;
}
return NULL;