Skip to content

block: pass a maxlen argument to bio_iov_iter_get_pages - #1248

Open
blktests-ci-kpd[bot] wants to merge 27 commits into
for-next_basefrom
series/1154182=>for-next
Open

blktests-ci-kpd[bot] wants to merge 27 commits into
for-next_basefrom
series/1154182=>for-next

Conversation

@blktests-ci-kpd

Copy link
Copy Markdown

Pull request for series with
subject: block: pass a maxlen argument to bio_iov_iter_get_pages
version: 1
url: https://patchwork.kernel.org/series/1154182/

@blktests-ci-kpd

Copy link
Copy Markdown
Author

Upstream branch: ba285ed
series: https://patchwork.kernel.org/series/1154182/
version: 1

Pull request is NOT updated. Failed to apply https://patchwork.kernel.org/series/1154182/
error message:

Cmd('git') failed due to: exit code(128)
  cmdline: git am --3way
  stdout: 'Patch is empty.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To record the empty patch as an empty commit, run "git am --allow-empty".
To restore the original branch and stop patching, run "git am --abort".'

conflict:


io_uring_try_cancel_uring_cmd() ignores the task it is asked to cancel
on behalf of as soon as cancel_all is true, and cancels every cancelable
command on the ring instead. That differs from how other requests are
matched, where a valid task always restricts matching to that task's
requests and cancel_all simply lifts the REQ_F_INFLIGHT restriction.

So far the only caller passing both a task and cancel_all is exec, where
tearing down another task's commands on a shared ring is somewhat
impolite. The exit path is about to do the same for every exiting
process though, so bring it in line. Match on the task if one is given,
and cancel everything only for ring teardown, which passes NULL. This
leaves cancel_all as useless, hence drop it.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
SEND_ZC notifications are io_kiocbs like any other as far as request
and task accounting goes, but they are special in that they cannot be
canceled and only complete once the network stack is done with the
data. With an unresponsive peer, that can take a while.

The exit and release paths are about to start waiting for requests to
finish so that the files they pin get released in a timely manner, and
notifications neither pin files nor finish in a timely manner. Keep a
per-ring count of them so those paths can leave them out.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
When a task exits, io_uring only cancels and waits for the few request
types that must not outlive it, and leaves everything else to be torn
down whenever the ring itself goes away. This happens from a kernel
workqueue, and may be some time after the final fput of the ring has
been completed. This sometimes causes application issues, where a task
that was doing IO on a file in /mnt, for example, will leave /mnt busy
for a brief period of time after close(ring_fd) is done.

If the whole thread group is exiting, no thread is left to reap
completions or care about those requests. For this case, tear everything
down. This is basically what exec does today.

Two types of requests are ignored, as they never pin any files and will
always complete on their own. One is armed timeouts, which may still be
required to trigger if a ring is being shared, and the other is SEND_ZC
notifications, which can take almost an unbounded time to complete.
io_uring_try_cancel_requests() now takes flags to manage that behavior.

While in there, fix up the wait loop for the exit case. A task that is
exiting because of a fatal signal still has that signal pending, which
turns the interruptible sleep into a busy loop. Use short
uninterruptible sleeps in that case instead, task_work still gets run in
between.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring_release() just marks the ring as dying and punts everything
else to exit_work, including the cancelation of requests that are easily
cancelable right away Until that work has run, and the task_work it
generates has as well, those requests keep their files pinned. An
application that closes its ring and then expects the files it had been
using to be closed as well may be confused by this currently not being
the case.

Re-factor the cancelation pass out of io_ring_exit_work() and run it
directly from release, before punting the rest.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Registered file and buffer tables are only torn down from
io_ring_ctx_free(), which only runs when all requests have completed and
the ctx refs have hit zero. Before this, every registered file remains
open.

The resource nodes are reference counted and any request using a
registered file or buffer holds its own reference to the node, so this
only releases what is actually unused. The rest follow as those requests
complete or get canceled.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
With cancelations now run at release time, what's left in-flight on
the ring afterwards is mostly I/O that has already been issued to a
device and just needs to finish. Until that happens, the files from
those requests pin the files they were using. Wait for those.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Once io-wq is done with the request, put any potential file that request
had pinned upfront. This ensures any file references are fully put by
the time io-wq posts a completion. For registered files we don't need to
worry about this, as these are canceled/dropped earlier.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
axboe and others added 3 commits September 9, 2026 09:59
* io_uring-7.3:
  io_uring/rw: keep CQE flags on iopoll requests when adding kbuf flags
  io_uring/net: don't overconsume buffers when using MSG_TRUNC
  io_uring/net: let io_recv_buf_select return the length of the buffer region
  io_uring/rw: end write accounting from ->ki_complete
* io_uring-exit-cancel.4:
  io_uring/io-wq: put the request file before posting a completion
  io_uring: wait for in-flight requests on ring release
  io_uring: drop registered files and buffers at release time
  io_uring: run cancelations synchronously on ring release
  io_uring/cancel: cancel and wait for all requests on process exit
  io_uring/notif: count pending zerocopy notifications per ring
  io_uring/uring_cmd: only cancel requests of the given task
Christoph Hellwig added 13 commits September 10, 2026 16:00
Writes that require additional per-I/O allocations such as when using
file system level protection information can be limited to a maximum
size.  Allow passing that to bio_iov_iter_get_pages.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Catch cases where upper layer bugs create larger I/Os than the
mempool would return even without dipping into the mempool.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Factor out a bio_alloc_bounce_folios helper that we'll use for a
different take on read-side bounce buffering soon.

For that make it and also bio_free_folios available to callers outside of
bio.c.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
We'll move integrity generation and verification into the iomap
submission helpers, which means they will be needed in modular file
system code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Respect the maximum I/O size set for PI-enabled I/O in
iomap_dio_bio_iter_one, otherwise bio_integrity_alloc_buf could
under-allocate the integrity buffer when the initial kmalloc fails.

Currently this should not be triggered as file systems that limit the
size for PI always use bounce buffering, but this will change soon.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Add a helper to initialize the ioend flags to the values that can be
directly derived from the iomap.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
This will make it easier to share code for the various submit callback
provided by the file system to iomap.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Currently the buffered I/O code defers PI handling into the submit
handlers, while direct I/O does it in common code.  Move the direct I/O
side into the file system callbacks or their generic implementations to
be consistent, and to allow file systems to shared helpers for submission
of buffered and direct bios.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Keep the code in one place, and do so only after splitting to
keep the allocation size down in case of a split.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
…c offset

When reconstructing a bvec_iter from an ioend for protection information
verification, iomap currently ignores the offset into the initial
bio_vec.

This can't happen for buffered I/O an direct I/O to user addresses, but
is exercised by split on O_DIRECT file descriptors or when using the loop
driver.

Fortunately the only file system PI user (XFS) currently always bounce
buffers, so this can't actually be triggered yet.  But we'll want to make
the bounce buffering conditional soon, for which this needs to be fixed.

Store the initial offset in struct iomap_ioend, and pass a
pre-constructed bvec_iter to fs_bio_integrity_verify.  For the
synchronous read case the fix is even simpler as this path can
simply stash away the original bvec_iter.

Fixes: 0bde8a1 ("block: add fs_bio_integrity helpers")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Add helpers to bounce buffer an upper bio into one or more lower bios
using bounce buffers, and to copy the data back on completion.

Compared to the existing IOMAP_DIO_BOUNCE support for read bios, this
has two advantages:  by removing the special bounce bio_vec it allows
to the full and "round" size of a single bio, i.e., 1MiB when using
4k pages.  This is important for good performance on HDD.  Additionally
it allows to bounce buffer a bio from completion conext, and thus
implement a "lazy" bounce buffering scheme, where the data is only
read into a bounce buffer after an initial checksum validation failure,
thus avoiding the bounce buffering I/O for most I/O.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Stop using the xfs per-inode work struct for completing read bios, as
unlike writes we don't want to serialize reads on a single inode as
there is no exclusive resource contention for them.

Factor the code for kicking off a read that needs and ioend and the
task context completion into a single helper so that it is split off
the xfs_end_bio machinery, which is not only used for writes.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Integrity support in file systems already requires file system-specific
completion handling because it must be run in process context.

Move the actual verification to the file system so that it can better
handle errors in file system specific ways, and to support lazy bounce
buffering.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Christoph Hellwig added 4 commits September 10, 2026 16:00
Currently direct I/O reads always bounce buffer the I/O to deal with
the case where userspace is modifying the buffer in-flight while
reading data into it.

This is a very expensive countermeasure for something no sane application
should do, so try to avoid it by reading without a bounce buffer first,
and retrying the read on a checksum failure.  This avoids the cost of
bounce buffering for sanely behave applications.  For the rare case of
an application regularly modifying in-flight buffers, allow forcing the
always bounce buffer behavior through sysfs.  And now that we have that
knob, allow disabling read-side bounce buffering entirely for those who
live fast and dangerous.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Add an error injection know to exercise the lazy bounce buffering
code path, i.e. to inject direct I/O re-read using the bounce buffer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Log a message in the kernel when using T10 protection information.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
bio_iov_iter_bounce_read turned to generate suboptimal I/O sizes and
isn't usable for lazy bounce buffering.  Now that is has been replaced
with the iomap side implementation that requires extra bounce bios, it
is unused and can be removed.  Change the interface so that the
previously hidden write-side implementation is directly exposed.

Signed-off-by: Christoph Hellwig <hch@lst.de>
@blktests-ci-kpd

Copy link
Copy Markdown
Author

Upstream branch: 9dcbf66
series: https://patchwork.kernel.org/series/1154182/
version: 1

@blktests-ci-kpd
blktests-ci-kpd Bot force-pushed the series/1154182=>for-next branch from 253597e to e2b0023 Compare September 10, 2026 16:00
@blktests-ci-kpd
blktests-ci-kpd Bot force-pushed the for-next_base branch 3 times, most recently from 1ec6755 to e2fca12 Compare September 15, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant