Skip to content
Snippets Groups Projects
  1. Jul 25, 2022
  2. Apr 25, 2022
  3. Apr 12, 2022
    • Jens Axboe's avatar
      io_uring: stop using io_wq_work as an fd placeholder · 82733d16
      Jens Axboe authored
      
      There are two reasons why this isn't the best idea:
      
      - It's an odd area to grab a bit of storage space, hence it's an odd area
        to grab storage from.
      - It puts the 3rd io_kiocb cacheline into the hot path, where normal hot
        path just needs the first two.
      
      Use 'cflags' for joint fd/cflags storage. We only need fd until we
      successfully issue, and we only need cflags once a request is done and is
      completed.
      
      Fixes: 6bf9c47a ("io_uring: defer file assignment")
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      82733d16
  4. Apr 07, 2022
    • Jens Axboe's avatar
      io_uring: defer file assignment · 6bf9c47a
      Jens Axboe authored
      
      If an application uses direct open or accept, it knows in advance what
      direct descriptor value it will get as it picks it itself. This allows
      combined requests such as:
      
      sqe = io_uring_get_sqe(ring);
      io_uring_prep_openat_direct(sqe, ..., file_slot);
      sqe->flags |= IOSQE_IO_LINK | IOSQE_CQE_SKIP_SUCCESS;
      
      sqe = io_uring_get_sqe(ring);
      io_uring_prep_read(sqe,file_slot, buf, buf_size, 0);
      sqe->flags |= IOSQE_FIXED_FILE;
      
      io_uring_submit(ring);
      
      where we prepare both a file open and read, and only get a completion
      event for the read when both have completed successfully.
      
      Currently links are fully prepared before the head is issued, but that
      fails if the dependent link needs a file assigned that isn't valid until
      the head has completed.
      
      Conversely, if the same chain is performed but the fixed file slot is
      already valid, then we would be unexpectedly returning data from the
      old file slot rather than the newly opened one. Make sure we're
      consistent here.
      
      Allow deferral of file setup, which makes this documented case work.
      
      Cc: stable@vger.kernel.org # v5.15+
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      6bf9c47a
  5. Jan 08, 2022
  6. Dec 07, 2021
  7. Oct 19, 2021
  8. Aug 29, 2021
    • Jens Axboe's avatar
      io-wq: provide a way to limit max number of workers · 2e480058
      Jens Axboe authored
      
      io-wq divides work into two categories:
      
      1) Work that completes in a bounded time, like reading from a regular file
         or a block device. This type of work is limited based on the size of
         the SQ ring.
      
      2) Work that may never complete, we call this unbounded work. The amount
         of workers here is just limited by RLIMIT_NPROC.
      
      For various uses cases, it's handy to have the kernel limit the maximum
      amount of pending workers for both categories. Provide a way to do with
      with a new IORING_REGISTER_IOWQ_MAX_WORKERS operation.
      
      IORING_REGISTER_IOWQ_MAX_WORKERS takes an array of two integers and sets
      the max worker count to what is being passed in for each category. The
      old values are returned into that same array. If 0 is being passed in for
      either category, it simply returns the current value.
      
      The value is capped at RLIMIT_NPROC. This actually isn't that important
      as it's more of a hint, if we're exceeding the value then our attempt
      to fork a new worker will fail. This happens naturally already if more
      than one node is in the system, as these values are per-node internally
      for io-wq.
      
      Reported-by: default avatarJohannes Lundberg <johalun0@gmail.com>
      Link: https://github.com/axboe/liburing/issues/420
      
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      2e480058
  9. Aug 23, 2021
  10. Jun 18, 2021
  11. Jun 17, 2021
    • Jens Axboe's avatar
      io_uring: allow user configurable IO thread CPU affinity · fe76421d
      Jens Axboe authored
      
      io-wq defaults to per-node masks for IO workers. This works fine by
      default, but isn't particularly handy for workloads that prefer more
      specific affinities, for either performance or isolation reasons.
      
      This adds IORING_REGISTER_IOWQ_AFF that allows the user to pass in a CPU
      mask that is then applied to IO thread workers, and an
      IORING_UNREGISTER_IOWQ_AFF that simply resets the masks back to the
      default of per-node.
      
      Note that no care is given to existing IO threads, they will need to go
      through a reschedule before the affinity is correct if they are already
      running or sleeping.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      fe76421d
  12. May 26, 2021
    • Pavel Begunkov's avatar
      io_uring/io-wq: close io-wq full-stop gap · 17a91051
      Pavel Begunkov authored
      
      There is an old problem with io-wq cancellation where requests should be
      killed and are in io-wq but are not discoverable, e.g. in @next_hashed
      or @linked vars of io_worker_handle_work(). It adds some unreliability
      to individual request canellation, but also may potentially get
      __io_uring_cancel() stuck. For instance:
      
      1) An __io_uring_cancel()'s cancellation round have not found any
         request but there are some as desribed.
      2) __io_uring_cancel() goes to sleep
      3) Then workers wake up and try to execute those hidden requests
         that happen to be unbound.
      
      As we already cancel all requests of io-wq there, set IO_WQ_BIT_EXIT
      in advance, so preventing 3) from executing unbound requests. The
      workers will initially break looping because of getting a signal as they
      are threads of the dying/exec()'ing user task.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
      Link: https://lore.kernel.org/r/abfcf8c54cb9e8f7bfbad7e9a0cc5433cc70bdc2.1621781238.git.asml.silence@gmail.com
      
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      17a91051
  13. Apr 12, 2021
    • Jens Axboe's avatar
      io-wq: eliminate the need for a manager thread · 685fe7fe
      Jens Axboe authored
      
      io-wq relies on a manager thread to create/fork new workers, as needed.
      But there's really no strong need for it anymore. We have the following
      cases that fork a new worker:
      
      1) Work queue. This is done from the task itself always, and it's trivial
         to create a worker off that path, if needed.
      
      2) All workers have gone to sleep, and we have more work. This is called
         off the sched out path. For this case, use a task_work items to queue
         a fork-worker operation.
      
      3) Hashed work completion. Don't think we need to do anything off this
         case. If need be, it could just use approach 2 as well.
      
      Part of this change is incrementing the running worker count before the
      fork, to avoid cases where we observe we need a worker and then queue
      creation of one. Then new work comes in, we fork a new one. That last
      queue operation should have waited for the previous worker to come up,
      it's quite possible we don't even need it. Hence move the worker running
      from before we fork it off to more efficiently handle that case.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      685fe7fe
  14. Mar 18, 2021
  15. Mar 06, 2021
  16. Mar 05, 2021
    • Jens Axboe's avatar
      io_uring: move to using create_io_thread() · 46fe18b1
      Jens Axboe authored
      
      This allows us to do task creation and setup without needing to use
      completions to try and synchronize with the starting thread. Get rid of
      the old io_wq_fork_thread() wrapper, and the 'wq' and 'worker' startup
      completion events - we can now do setup before the task is running.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      46fe18b1
  17. Mar 04, 2021
    • Jens Axboe's avatar
      io_uring: move cred assignment into io_issue_sqe() · 5730b27e
      Jens Axboe authored
      
      If we move it in there, then we no longer have to care about it in io-wq.
      This means we can drop the cred handling in io-wq, and we can drop the
      REQ_F_WORK_INITIALIZED flag and async init functions as that was the last
      user of it since we moved to the new workers. Then we can also drop
      io_wq_work->creds, and just hold the personality u16 in there instead.
      
      Suggested-by: default avatarPavel Begunkov <asml.silence@gmail.com>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      5730b27e
    • Jens Axboe's avatar
      io-wq: provide an io_wq_put_and_exit() helper · afcc4015
      Jens Axboe authored
      
      If we put the io-wq from io_uring, we really want it to exit. Provide
      a helper that does that for us. Couple that with not having the manager
      hold a reference to the 'wq' and the normal SQPOLL exit will tear down
      the io-wq context appropriate.
      
      On the io-wq side, our wq context is per task, so only the task itself
      is manipulating ->manager and hence it's safe to check and clear without
      any extra locking. We just need to ensure that the manager task stays
      around, in case it exits.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      afcc4015
  18. Feb 25, 2021
    • Jens Axboe's avatar
      io-wq: improve manager/worker handling over exec · 4fb6ac32
      Jens Axboe authored
      
      exec will cancel any threads, including the ones that io-wq is using. This
      isn't a problem, in fact we'd prefer it to be that way since it means we
      know that any async work cancels naturally without having to handle it
      proactively.
      
      But it does mean that we need to setup a new manager, as the manager and
      workers are gone. Handle this at queue time, and cancel work if we fail.
      Since the manager can go away without us noticing, ensure that the manager
      itself holds a reference to the 'wq' as well. Rename io_wq_destroy() to
      io_wq_put() to reflect that.
      
      In the future we can now simplify exec cancelation handling, for now just
      leave it the same.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      4fb6ac32
    • Jens Axboe's avatar
      io-wq: make buffered file write hashed work map per-ctx · e941894e
      Jens Axboe authored
      
      Before the io-wq thread change, we maintained a hash work map and lock
      per-node per-ring. That wasn't ideal, as we really wanted it to be per
      ring. But now that we have per-task workers, the hash map ends up being
      just per-task. That'll work just fine for the normal case of having
      one task use a ring, but if you share the ring between tasks, then it's
      considerably worse than it was before.
      
      Make the hash map per ctx instead, which provides full per-ctx buffered
      write serialization on hashed writes.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      e941894e
  19. Feb 24, 2021
    • Jens Axboe's avatar
      io-wq: remove nr_process accounting · 728f13e7
      Jens Axboe authored
      
      We're now just using fork like we would from userspace, so there's no
      need to try and impose extra restrictions or accounting on the user
      side of things. That's already being done for us. That also means we
      don't have to pass in the user_struct anymore, that's correctly inherited
      through ->creds on fork.
      
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      728f13e7
  20. Feb 22, 2021
  21. Feb 10, 2021
  22. Feb 04, 2021
  23. Feb 01, 2021
  24. Dec 20, 2020
  25. Dec 18, 2020
    • Xiaoguang Wang's avatar
      io_uring: fix io_wqe->work_list corruption · 0020ef04
      Xiaoguang Wang authored
      
      For the first time a req punted to io-wq, we'll initialize io_wq_work's
      list to be NULL, then insert req to io_wqe->work_list. If this req is not
      inserted into tail of io_wqe->work_list, this req's io_wq_work list will
      point to another req's io_wq_work. For splitted bio case, this req maybe
      inserted to io_wqe->work_list repeatedly, once we insert it to tail of
      io_wqe->work_list for the second time, now io_wq_work->list->next will be
      invalid pointer, which then result in many strang error, panic, kernel
      soft-lockup, rcu stall, etc.
      
      In my vm, kernel doest not have commit cc29e1bf ("block: disable
      iopoll for split bio"), below fio job can reproduce this bug steadily:
      [global]
      name=iouring-sqpoll-iopoll-1
      ioengine=io_uring
      iodepth=128
      numjobs=1
      thread
      rw=randread
      direct=1
      registerfiles=1
      hipri=1
      bs=4m
      size=100M
      runtime=120
      time_based
      group_reporting
      randrepeat=0
      
      [device]
      directory=/home/feiman.wxg/mntpoint/  # an ext4 mount point
      
      If we have commit cc29e1bf ("block: disable iopoll for split bio"),
      there will no splitted bio case for polled io, but I think we still to need
      to fix this list corruption, it also should maybe go to stable branchs.
      
      To fix this corruption, if a req is inserted into tail of io_wqe->work_list,
      initialize req->io_wq_work->list->next to bu NULL.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarXiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
      Reviewed-by: default avatarPavel Begunkov <asml.silence@gmail.com>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      0020ef04
  26. Dec 09, 2020
  27. Oct 21, 2020
  28. Oct 17, 2020
Loading