io_uring: allow submissions to continue on error
authorJens Axboe <axboe@kernel.dk>
Thu, 10 Mar 2022 19:59:35 +0000 (12:59 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 10 Mar 2022 20:05:25 +0000 (13:05 -0700)
By default, io_uring will stop submitting a batch of requests if we run
into an error submitting a request. This isn't strictly necessary, as
the error result is passed out-of-band via a CQE anyway. And it can be
a bit confusing for some applications.

Provide a way to setup a ring that will continue submitting on error,
when the error CQE has been posted.

There's still one case that will break out of submission. If we fail
allocating a request, then we'll still return -ENOMEM. We could in theory
post a CQE for that condition too even if we never got a request. Leave
that for a potential followup.

Reported-by: Dylan Yudaken <dylany@fb.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c
include/uapi/linux/io_uring.h

index 3145c9c..229b31d 100644 (file)
@@ -7801,8 +7801,14 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr)
                }
                /* will complete beyond this point, count as submitted */
                submitted++;
-               if (io_submit_sqe(ctx, req, sqe))
-                       break;
+               if (io_submit_sqe(ctx, req, sqe)) {
+                       /*
+                        * Continue submitting even for sqe failure if the
+                        * ring was setup with IORING_SETUP_SUBMIT_ALL
+                        */
+                       if (!(ctx->flags & IORING_SETUP_SUBMIT_ALL))
+                               break;
+               }
        } while (submitted < nr);
 
        if (unlikely(submitted != nr)) {
@@ -11265,7 +11271,7 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params)
        if (p.flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL |
                        IORING_SETUP_SQ_AFF | IORING_SETUP_CQSIZE |
                        IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ |
-                       IORING_SETUP_R_DISABLED))
+                       IORING_SETUP_R_DISABLED | IORING_SETUP_SUBMIT_ALL))
                return -EINVAL;
 
        return  io_uring_create(entries, &p, params);
index 8bd4bfd..d2be4eb 100644 (file)
@@ -101,6 +101,7 @@ enum {
 #define IORING_SETUP_CLAMP     (1U << 4)       /* clamp SQ/CQ ring sizes */
 #define IORING_SETUP_ATTACH_WQ (1U << 5)       /* attach to existing wq */
 #define IORING_SETUP_R_DISABLED        (1U << 6)       /* start with ring disabled */
+#define IORING_SETUP_SUBMIT_ALL        (1U << 7)       /* continue submit on error */
 
 enum {
        IORING_OP_NOP,