diff --git a/emper/io/IoContext.cpp b/emper/io/IoContext.cpp index bc5300f8b6cd81bc4c5ac4c8bb3079070eb8a9b2..473f8924ee2c4956e9fad2d54e0d4408ba225ab7 100644 --- a/emper/io/IoContext.cpp +++ b/emper/io/IoContext.cpp @@ -133,13 +133,18 @@ void IoContext::submit(Future &future) { // Because we submit every Future right away multiple prepared sqes can only // occur for Future chains. // If we could not submit the whole chain cancel all non submitted Futures - // because we can not guaranty the soundness of the chain and invalidate their - // prepared sqe + // because we can not guaranty the soundness of the chain have to invalidate + // non submitted but prepared sqes // req1 -> invalid_req -> req3 // will submit only 2 instead of all 3 prepared sqes leaving a sqe for req3 // in the SQ but unsubmitted // See: https://github.com/axboe/liburing/issues/186 // https://github.com/axboe/liburing/issues/92 + // + // Since kernel commit cf10960426515 io_uring does no longer submit parts of a + // broken chains. This means that all sqes in a chain except the broken one will + // result in cqes with result -ECANCELD and the invalid one will + // generate a cqe with the appropriate error code if (unlikely(static_cast<unsigned>(submitted) < prepared)) { unsigned unsubmitted = io_uring_sq_ready(&ring); Future *unsubmittedFuture = &future; diff --git a/tests/io/LinkFutureTest.cpp b/tests/io/LinkFutureTest.cpp index 14c15cb0c272ca62b6757e48bc84039c604ddc79..94291c21af6eeef1ee696c9f155ee0a227d6f410 100644 --- a/tests/io/LinkFutureTest.cpp +++ b/tests/io/LinkFutureTest.cpp @@ -119,7 +119,10 @@ static void failureChainCorInvCor() { assert(res == -EBADF); res = correctFuture1.wait(); - assert(res == (int32_t)buf.size()); + // Since the kernel commit cf10960426515 io_uring does not + // submit broken links and completes any request before a + // invalid one as canceled. + assert(res == -ECANCELED || res == (int32_t)buf.size()); emper::io::closeAndWait(fd); }