src/queue: don't loop when don't enter
_io_uring_get_cqe() can live-lock in some cases, always return if we're
not going to do __sys_io_uring_enter().
Reported-by: Victor Stewart
Suggested-by: Jens Axboe
@@ -89,12 +89,13 @@ static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_pt
{
struct io_uring_cqe *cqe = NULL;
const int to_wait = data->wait_nr;
- int ret = 0, err;
+ int err;
do {
bool cq_overflow_flush = false;
unsigned flags = 0;
unsigned nr_available;
+ int ret;
err = __io_uring_peek_cqe(ring, &cqe, &nr_available);
if (err)
@@ -110,8 +111,10 @@ static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_pt
flags = IORING_ENTER_GETEVENTS | data->get_flags;
if (data->submit)
sq_ring_needs_enter(ring, &flags);
- if (data->wait_nr > nr_available || data->submit ||
- cq_overflow_flush)
+ if (data->wait_nr <= nr_available && !data->submit &&
+ !cq_overflow_flush)
+ break;
+
ret = __sys_io_uring_enter2(ring->ring_fd, data->submit,
data->wait_nr, flags, data->arg,
data->sz);
