Merge tag 'for-5.5/io_uring-20191121' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Nov 2019 18:40:27 +0000 (10:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Nov 2019 18:40:27 +0000 (10:40 -0800)
Pull io_uring updates from Jens Axboe:
 "A lot of stuff has been going on this cycle, with improving the
  support for networked IO (and hence unbounded request completion
  times) being one of the major themes. There's been a set of fixes done
  this week, I'll send those out as well once we're certain we're fully
  happy with them.

  This contains:

   - Unification of the "normal" submit path and the SQPOLL path (Pavel)

   - Support for sparse (and bigger) file sets, and updating of those
     file sets without needing to unregister/register again.

   - Independently sized CQ ring, instead of just making it always 2x
     the SQ ring size. This makes it more flexible for networked
     applications.

   - Support for overflowed CQ ring, never dropping events but providing
     backpressure on submits.

   - Add support for absolute timeouts, not just relative ones.

   - Support for generic cancellations. This divorces io_uring from
     workqueues as well, which additionally gets us one step closer to
     generic async system call support.

   - With cancellations, we can support grabbing the process file table
     as well, just like we do mm context. This allows support for system
     calls that create file descriptors, like accept4() support that's
     built on top of that.

   - Support for io_uring tracing (Dmitrii)

   - Support for linked timeouts. These abort an operation if it isn't
     completed by the time noted in the linke timeout.

   - Speedup tracking of poll requests

   - Various cleanups making the coder easier to follow (Jackie, Pavel,
     Bob, YueHaibing, me)

   - Update MAINTAINERS with new io_uring list"

* tag 'for-5.5/io_uring-20191121' of git://git.kernel.dk/linux-block: (64 commits)
  io_uring: make POLL_ADD/POLL_REMOVE scale better
  io-wq: remove now redundant struct io_wq_nulls_list
  io_uring: Fix getting file for non-fd opcodes
  io_uring: introduce req_need_defer()
  io_uring: clean up io_uring_cancel_files()
  io-wq: ensure free/busy list browsing see all items
  io-wq: ensure we have a stable view of ->cur_work for cancellations
  io_wq: add get/put_work handlers to io_wq_create()
  io_uring: check for validity of ->rings in teardown
  io_uring: fix potential deadlock in io_poll_wake()
  io_uring: use correct "is IO worker" helper
  io_uring: fix -ENOENT issue with linked timer with short timeout
  io_uring: don't do flush cancel under inflight_lock
  io_uring: flag SQPOLL busy condition to userspace
  io_uring: make ASYNC_CANCEL work with poll and timeout
  io_uring: provide fallback request for OOM situations
  io_uring: convert accept4() -ERESTARTSYS into -EINTR
  io_uring: fix error clear of ->file_table in io_sqe_files_register()
  io_uring: separate the io_free_req and io_free_req_find_next interface
  io_uring: keep io_put_req only responsible for release and put req
  ...

1  2 
MAINTAINERS
fs/io_uring.c
include/Kbuild
include/linux/socket.h
kernel/sched/core.c
net/socket.c

diff --cc MAINTAINERS
Simple merge
diff --cc fs/io_uring.c
@@@ -326,7 -343,8 +343,9 @@@ struct io_kiocb 
  #define REQ_F_TIMEOUT         1024    /* timeout request */
  #define REQ_F_ISREG           2048    /* regular file */
  #define REQ_F_MUST_PUNT               4096    /* must be punted even for NONBLOCK */
 -#define REQ_F_INFLIGHT                8192    /* on inflight list */
 -#define REQ_F_COMP_LOCKED     16384   /* completion under lock */
 +#define REQ_F_TIMEOUT_NOSEQ   8192    /* no timeout sequence */
++#define REQ_F_INFLIGHT                16384   /* on inflight list */
++#define REQ_F_COMP_LOCKED     32768   /* completion under lock */
        u64                     user_data;
        u32                     result;
        u32                     sequence;
@@@ -454,13 -485,9 +486,13 @@@ static struct io_kiocb *io_get_timeout_
        struct io_kiocb *req;
  
        req = list_first_entry_or_null(&ctx->timeout_list, struct io_kiocb, list);
 -      if (req && !__req_need_defer(req)) {
 -              list_del_init(&req->list);
 -              return req;
 +      if (req) {
 +              if (req->flags & REQ_F_TIMEOUT_NOSEQ)
 +                      return NULL;
-               if (!__io_sequence_defer(ctx, req)) {
++              if (!__req_need_defer(req)) {
 +                      list_del_init(&req->list);
 +                      return req;
 +              }
        }
  
        return NULL;
@@@ -1946,7 -2334,12 +2340,13 @@@ static int io_timeout(struct io_kiocb *
        if (get_timespec64(&ts, u64_to_user_ptr(sqe->addr)))
                return -EFAULT;
  
+       if (flags & IORING_TIMEOUT_ABS)
+               mode = HRTIMER_MODE_ABS;
+       else
+               mode = HRTIMER_MODE_REL;
+       hrtimer_init(&req->timeout.timer, CLOCK_MONOTONIC, mode);
 +      req->flags |= REQ_F_TIMEOUT;
  
        /*
         * sqe->off holds how many events that need to occur for this
                nxt->sequence++;
        }
        req->sequence -= span;
 +add:
        list_add(&req->list, entry);
+       req->timeout.timer.function = io_timeout_fn;
+       hrtimer_start(&req->timeout.timer, timespec64_to_ktime(ts), mode);
        spin_unlock_irq(&ctx->completion_lock);
+       return 0;
+ }
  
-       hrtimer_init(&req->timeout.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-       req->timeout.timer.function = io_timeout_fn;
-       hrtimer_start(&req->timeout.timer, timespec64_to_ktime(ts),
-                       HRTIMER_MODE_REL);
+ static bool io_cancel_cb(struct io_wq_work *work, void *data)
+ {
+       struct io_kiocb *req = container_of(work, struct io_kiocb, work);
+       return req->user_data == (unsigned long) data;
+ }
+ static int io_async_cancel_one(struct io_ring_ctx *ctx, void *sqe_addr)
+ {
+       enum io_wq_cancel cancel_ret;
+       int ret = 0;
+       cancel_ret = io_wq_cancel_cb(ctx->io_wq, io_cancel_cb, sqe_addr);
+       switch (cancel_ret) {
+       case IO_WQ_CANCEL_OK:
+               ret = 0;
+               break;
+       case IO_WQ_CANCEL_RUNNING:
+               ret = -EALREADY;
+               break;
+       case IO_WQ_CANCEL_NOTFOUND:
+               ret = -ENOENT;
+               break;
+       }
+       return ret;
+ }
+ static void io_async_find_and_cancel(struct io_ring_ctx *ctx,
+                                    struct io_kiocb *req, __u64 sqe_addr,
+                                    struct io_kiocb **nxt)
+ {
+       unsigned long flags;
+       int ret;
+       ret = io_async_cancel_one(ctx, (void *) (unsigned long) sqe_addr);
+       if (ret != -ENOENT) {
+               spin_lock_irqsave(&ctx->completion_lock, flags);
+               goto done;
+       }
+       spin_lock_irqsave(&ctx->completion_lock, flags);
+       ret = io_timeout_cancel(ctx, sqe_addr);
+       if (ret != -ENOENT)
+               goto done;
+       ret = io_poll_cancel(ctx, sqe_addr);
+ done:
+       io_cqring_fill_event(req, ret);
+       io_commit_cqring(ctx);
+       spin_unlock_irqrestore(&ctx->completion_lock, flags);
+       io_cqring_ev_posted(ctx);
+       if (ret < 0 && (req->flags & REQ_F_LINK))
+               req->flags |= REQ_F_FAIL_LINK;
+       io_put_req_find_next(req, nxt);
+ }
+ static int io_async_cancel(struct io_kiocb *req, const struct io_uring_sqe *sqe,
+                          struct io_kiocb **nxt)
+ {
+       struct io_ring_ctx *ctx = req->ctx;
+       if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
+               return -EINVAL;
+       if (sqe->flags || sqe->ioprio || sqe->off || sqe->len ||
+           sqe->cancel_flags)
+               return -EINVAL;
+       io_async_find_and_cancel(ctx, req, READ_ONCE(sqe->addr), NULL);
        return 0;
  }
  
diff --cc include/Kbuild
Simple merge
Simple merge
Simple merge
diff --cc net/socket.c
Simple merge