engines/libaio: fix io_getevents min/max events arguments
authorLeah Rumancik <leah.rumancik@gmail.com>
Fri, 7 Apr 2023 20:41:03 +0000 (13:41 -0700)
committerLeah Rumancik <leah.rumancik@gmail.com>
Fri, 7 Apr 2023 20:45:52 +0000 (13:45 -0700)
If the io_getevents system call is interrupted, it can succeed while
returning less than the min_nr requested events. If this occurs during
the final reaping of events, libaio will call io_getevents again wtih
the same minimum events argument. Since some of the events have already
been reaped, this results in a hang. To fix this, update the arguments
for io_getevents based on the previously seen events.

Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
engines/libaio.c

index 33b8c12f96fb191af478114d1a1feb563ffb0440..1b82c90b751592ac98c964168c7f58a4f0fea56a 100644 (file)
@@ -288,14 +288,16 @@ static int fio_libaio_getevents(struct thread_data *td, unsigned int min,
                    && actual_min == 0
                    && ((struct aio_ring *)(ld->aio_ctx))->magic
                                == AIO_RING_MAGIC) {
-                       r = user_io_getevents(ld->aio_ctx, max,
+                       r = user_io_getevents(ld->aio_ctx, max - events,
                                ld->aio_events + events);
                } else {
                        r = io_getevents(ld->aio_ctx, actual_min,
-                               max, ld->aio_events + events, lt);
+                               max - events, ld->aio_events + events, lt);
                }
-               if (r > 0)
+               if (r > 0) {
                        events += r;
+                       actual_min = actual_min > events ? actual_min - events : 0;
+               }
                else if ((min && r == 0) || r == -EAGAIN) {
                        fio_libaio_commit(td);
                        if (actual_min)