1. 23 Mar, 2022 4 commits
    • 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
    • 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-g8565d644 #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: 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
  2. 22 Mar, 2022 1 commit
    • 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
  3. 21 Mar, 2022 1 commit
  4. 20 Mar, 2022 2 commits
    • Jens Axboe's avatar
      io_uring: ensure that fsnotify is always called · f63cf519
      Jens Axboe authored
      Ensure that we call fsnotify_modify() if we write a file, and that we
      do fsnotify_access() if we read it. This enables anyone using inotify
      on the file to get notified.
      
      Ditto for fallocate, ensure that fsnotify_modify() is called.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      f63cf519
    • 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
  5. 18 Mar, 2022 2 commits
  6. 17 Mar, 2022 9 commits
  7. 16 Mar, 2022 4 commits
    • Jens Axboe's avatar
      io_uring: cache poll/double-poll state with a request flag · 91eac1c6
      Jens Axboe authored
      With commit "io_uring: cache req->apoll->events in req->cflags" applied,
      we now have just io_poll_remove_entries() dipping into req->apoll when
      it isn't strictly necessary.
      
      Mark poll and double-poll with a flag, so we know if we need to look
      at apoll->double_poll. This avoids pulling in those cachelines if we
      don't need them. The common case is that the poll wake handler already
      removed these entries while hot off the completion path.
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      91eac1c6
    • Jens Axboe's avatar
      io_uring: cache req->apoll->events in req->cflags · 81459350
      Jens Axboe authored
      When we arm poll on behalf of a different type of request, like a network
      receive, then we allocate req->apoll as our poll entry. Running network
      workloads shows io_poll_check_events() as the most expensive part of
      io_uring, and it's all due to having to pull in req->apoll instead of
      just the request which we have hot already.
      
      Cache poll->events in req->cflags, which isn't used until the request
      completes anyway. This isn't strictly needed for regular poll, where
      req->poll.events is used and thus already hot, but for the sake of
      unification we do it all around.
      
      This saves 3-4% of overhead in certain request workloads.
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      81459350
    • Jens Axboe's avatar
      io_uring: move req->poll_refs into previous struct hole · 521d61fc
      Jens Axboe authored
      This serves two purposes:
      
      - We now have the last cacheline mostly unused for generic workloads,
        instead of having to pull in the poll refs explicitly for workloads
        that rely on poll arming.
      
      - It shrinks the io_kiocb from 232 to 224 bytes.
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      521d61fc
    • 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.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
      052ebf1f
  8. 15 Mar, 2022 1 commit
    • 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
  9. 12 Mar, 2022 1 commit
  10. 10 Mar, 2022 15 commits