Skip to content
  1. Mar 26, 2022
  2. Mar 25, 2022
  3. Mar 24, 2022
    • Jens Axboe's avatar
      io_uring: remove IORING_CQE_F_MSG · 7ef66d18
      Jens Axboe authored
      
      
      This was introduced with the message ring opcode, but isn't strictly
      required for the request itself. The sender can encode what is needed
      in user_data, which is passed to the receiver. It's unclear if having
      a separate flag that essentially says "This CQE did not originate from
      an SQE on this ring" provides any real utility to applications. While
      we can always re-introduce a flag to provide this information, we cannot
      take it away at a later point in time.
      
      Remove the flag while we still can, before it's in a released kernel.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      7ef66d18
    • Jens Axboe's avatar
      io_uring: add flag for disabling provided buffer recycling · 8a3e8ee5
      Jens Axboe authored
      
      
      If we need to continue doing this IO, then we don't want a potentially
      selected buffer recycled. Add a flag for that.
      
      Set this for recv/recvmsg if they do partial IO.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      8a3e8ee5
    • Jens Axboe's avatar
      io_uring: ensure recv and recvmsg handle MSG_WAITALL correctly · 7ba89d2a
      Jens Axboe authored
      
      
      We currently don't attempt to get the full asked for length even if
      MSG_WAITALL is set, if we get a partial receive. If we do see a partial
      receive, then just note how many bytes we did and return -EAGAIN to
      get it retried.
      
      The iov is advanced appropriately for the vector based case, and we
      manually bump the buffer and remainder for the non-vector case.
      
      Cc: stable@vger.kernel.org
      Reported-by: default avatarConstantine Gavrilov <constantine.gavrilov@gmail.com>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      7ba89d2a
  4. Mar 23, 2022
    • Jens Axboe's avatar
      io_uring: don't recycle provided buffer if punted to async worker · 4d55f238
      Jens Axboe authored
      We only really need to recycle the buffer when going async for a file
      type that has an indefinite reponse time (eg non-file/bdev). And for
      files that to arm poll, the async worker will arm poll anyway and the
      buffer will get recycled there.
      
      In that latter case, we're not holding ctx->uring_lock. Ensure we take
      the issue_flags into account and acquire it if we need to.
      
      Fixes: b1c62645
      
       ("io_uring: recycle provided buffers if request goes async")
      Reported-by: default avatarStefan Roesch <shr@fb.com>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      4d55f238
    • Jens Axboe's avatar
      io_uring: fix assuming triggered poll waitqueue is the single poll · d89a4fac
      Jens Axboe authored
      syzbot reports a recent regression:
      
      BUG: KASAN: use-after-free in __wake_up_common+0x637/0x650 kernel/sched/wait.c:101
      Read of size 8 at addr ffff888011e8a130 by task syz-executor413/3618
      
      CPU: 0 PID: 3618 Comm: syz-executor413 Tainted: G        W         5.17.0-syzkaller-01402-g8565d64430f8 #0
      Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
      Call Trace:
       <TASK>
       __dump_stack lib/dump_stack.c:88 [inline]
       dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
       print_address_description.constprop.0.cold+0x8d/0x303 mm/kasan/report.c:255
       __kasan_report mm/kasan/report.c:442 [inline]
       kasan_report.cold+0x83/0xdf mm/kasan/report.c:459
       __wake_up_common+0x637/0x650 kernel/sched/wait.c:101
       __wake_up_common_lock+0xd0/0x130 kernel/sched/wait.c:138
       tty_release+0x657/0x1200 drivers/tty/tty_io.c:1781
       __fput+0x286/0x9f0 fs/file_table.c:317
       task_work_run+0xdd/0x1a0 kernel/task_work.c:164
       exit_task_work include/linux/task_work.h:32 [inline]
       do_exit+0xaff/0x29d0 kernel/exit.c:806
       do_group_exit+0xd2/0x2f0 kernel/exit.c:936
       __do_sys_exit_group kernel/exit.c:947 [inline]
       __se_sys_exit_group kernel/exit.c:945 [inline]
       __x64_sys_exit_group+0x3a/0x50 kernel/exit.c:945
       do_syscall_x64 arch/x86/entry/common.c:50 [inline]
       do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
       entry_SYSCALL_64_after_hwframe+0x44/0xae
      RIP: 0033:0x7f439a1fac69
      
      which is due to leaving the request on the waitqueue mistakenly. The
      reproducer is using a tty device, which means we end up arming the same
      poll queue twice (it uses the same poll waitqueue for both), but in
      io_poll_wake() we always just clear REQ_F_SINGLE_POLL regardless of which
      entry triggered. This leaves one waitqueue potentially armed after we're
      done, which then blows up in tty when the waitqueue is attempted removed.
      
      We have no room to store this information, so simply encode it in the
      wait_queue_entry->private where we store the io_kiocb request pointer.
      
      Fixes: 91eac1c6
      
       ("io_uring: cache poll/double-poll state with a request flag")
      Reported-by: default avatar <syzbot+09ad4050dd3a120bfccd@syzkaller.appspotmail.com>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      d89a4fac
    • Jens Axboe's avatar
      io_uring: bump poll refs to full 31-bits · e2c0cb7c
      Jens Axboe authored
      The previous commit:
      
      1bc84c40088 ("io_uring: remove poll entry from list when canceling all")
      
      removed a potential overflow condition for the poll references. They
      are currently limited to 20-bits, even if we have 31-bits available. The
      upper bit is used to mark for cancelation.
      
      Bump the poll ref space to 31-bits, making that kind of situation much
      harder to trigger in general. We'll separately add overflow checking
      and handling.
      
      Fixes: aa43477b
      
       ("io_uring: poll rework")
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      e2c0cb7c
  5. Mar 22, 2022
    • Jens Axboe's avatar
      io_uring: remove poll entry from list when canceling all · 61bc84c4
      Jens Axboe authored
      When the ring is exiting, as part of the shutdown, poll requests are
      removed. But io_poll_remove_all() does not remove entries when finding
      them, and since completions are done out-of-band, we can find and remove
      the same entry multiple times.
      
      We do guard the poll execution by poll ownership, but that does not
      exclude us from reissuing a new one once the previous removal ownership
      goes away.
      
      This can race with poll execution as well, where we then end up seeing
      req->apoll be NULL because a previous task_work requeue finished the
      request.
      
      Remove the poll entry when we find it and get ownership of it. This
      prevents multiple invocations from finding it.
      
      Fixes: aa43477b
      
       ("io_uring: poll rework")
      Reported-by: default avatarDylan Yudaken <dylany@fb.com>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      61bc84c4
  6. Mar 21, 2022
  7. Mar 20, 2022
    • Jens Axboe's avatar
      io_uring: recycle provided before arming poll · abdad709
      Jens Axboe authored
      We currently have a race where we recycle the selected buffer if poll
      returns IO_APOLL_OK. But that's too late, as the poll could already be
      triggering or have triggered. If that race happens, then we're putting a
      buffer that's already being used.
      
      Fix this by recycling before we arm poll. This does mean that we'll
      sometimes almost instantly re-select the buffer, but it's rare enough in
      testing that it should not pose a performance issue.
      
      Fixes: b1c62645
      
       ("io_uring: recycle provided buffers if request goes async")
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      abdad709
  8. Mar 19, 2022
  9. Mar 18, 2022
    • Jens Axboe's avatar
      io_uring: manage provided buffers strictly ordered · dbc7d452
      Jens Axboe authored
      
      
      Workloads using provided buffers benefit from using and returning buffers
      in the right order, and so does TLBs for that matter. Manage the internal
      buffer list in a straight list, rather than use the head buffer as the
      insertion node. Use a hashed list for the buffer group IDs instead of
      xarray, the overhead is much lower this way. xarray provides internal
      locking and other trickery that is handy for some uses cases, but
      io_uring already locks internally for the buffer manipulation and needs
      none of that.
      
      This is good for about a 2% reduction in overhead, combination of the
      improved management and the fact that the workload has an easier time
      bundling back provided buffers.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      dbc7d452
  10. Mar 17, 2022
  11. Mar 16, 2022
    • Dylan Yudaken's avatar
      io_uring: make tracing format consistent · 052ebf1f
      Dylan Yudaken authored
      
      
      Make the tracing formatting for user_data and flags consistent.
      
      Having consistent formatting allows one for example to grep for a specific
      user_data/flags and be able to trace a single sqe through easily.
      
      Change user_data to 0x%llx and flags to 0x%x everywhere. The '0x' is
      useful to disambiguate for example "user_data 100".
      
      Additionally remove the '=' for flags in io_uring_req_failed, again for consistency.
      
      Signed-off-by: default avatarDylan Yudaken <dylany@fb.com>
      Link: https://lore.kernel.org/r/20220316095204.2191498-1-dylany@fb.com
      
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      052ebf1f
    • Jens Axboe's avatar
      io_uring: recycle apoll_poll entries · 4d9237e3
      Jens Axboe authored
      
      
      Particularly for networked workloads, io_uring intensively uses its
      poll based backend to get a notification when data/space is available.
      Profiling workloads, we see 3-4% of alloc+free that is directly attributed
      to just the apoll allocation and free (and the rest being skb alloc+free).
      
      For the fast path, we have ctx->uring_lock held already for both issue
      and the inline completions, and we can utilize that to avoid any extra
      locking needed to have a basic recycling cache for the apoll entries on
      both the alloc and free side.
      
      Double poll still requires an allocation. But those are rare and not
      a fast path item.
      
      With the simple cache in place, we see a 3-4% reduction in overhead for
      the workload.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      4d9237e3
  12. Mar 12, 2022
  13. Mar 11, 2022