-
Notifications
You must be signed in to change notification settings - Fork 2k
true async io in linux #18684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tiehexue
wants to merge
32
commits into
openzfs:master
Choose a base branch
from
tiehexue:true_async
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,533
−97
Open
true async io in linux #18684
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
fc6e8ac
true async io in linux
tiehexue 926de80
enforced O_DIRECT flag in async path
tiehexue a5c316d
aggregate errors in root zio
tiehexue 82e0727
do more checks as zfs_setup_direct
tiehexue b738584
pin 2x pages should be incorrect
tiehexue 457b328
made it PASS if libio or io_uring not found
tiehexue d75d956
move async io related code to linux os directory
tiehexue cf43b6e
abstract read/write async state/callback
tiehexue fe9e4aa
ensure uio_remove called after tx assign
tiehexue a504a89
ensure correctly return EIOCBQUEUED in all path
tiehexue c4e77cd
not necessary to check zfs_dio_strict here
tiehexue 50a13ae
do not try sync in async callback when failed
tiehexue 9f134e1
removed flag which doesn't make sense for write
tiehexue 19b0e0a
removed duplicate code between sync and async
tiehexue abd2d03
removed reduntant io_uring checking
tiehexue 3394eb3
added two static inline helper for clean code
tiehexue c61cd5e
clean code
tiehexue da074ca
save and restore in case fallback to sync path
tiehexue 9c2ab43
fio_ioengine_available is actually working now
tiehexue 0c009ef
zfs_write_async: gate on block alignment before ABD dispatch
mkhllr 7ca726c
zfs_write_async: fix tx abort and iov_iter desync on copy failure
mkhllr b9853fb
zfs_async_read_complete: do not leak ECKSUM to userspace on DIO read
mkhllr e5da022
zfs_async_write_task: commit assigned tx on write error, not abort
mkhllr 9963849
zfs_vnops_os: drain async DIO in teardown, not cross-thread unlock
mkhllr ad4eea5
clean the comments while code is removed
tiehexue 80bdd56
fix compilation after rebase with latest master
tiehexue 93d4f94
retry in async read complete when ECKSUM
tiehexue b2e686f
fix an unexpected parameter renaming when rebasing
tiehexue ee3c8fe
added tests to see how IOPS differs for numbjobs
tiehexue 674b1b2
removed cb->dio and corrected flag in zil commit
tiehexue 418a8fb
fallback when size greater than SPA_MAXBLOCKSIZE
tiehexue 00f118b
align sa_bulk_update to sync path and code cleaned
tiehexue File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| dnl # SPDX-License-Identifier: CDDL-1.0 | ||
| dnl # | ||
| dnl # 5.19 API change, | ||
| dnl # kiocb->ki_complete() reduced from 3 args to 2: | ||
| dnl # old: void (*ki_complete)(struct kiocb *, long, long) | ||
| dnl # new: void (*ki_complete)(struct kiocb *, long) | ||
| dnl # | ||
| AC_DEFUN([ZFS_AC_KERNEL_SRC_KIOCB_KI_COMPLETE], [ | ||
| ZFS_LINUX_TEST_SRC([kiocb_ki_complete_2args], [ | ||
| #include <linux/fs.h> | ||
| ],[ | ||
| struct kiocb *kiocb = NULL; | ||
| kiocb->ki_complete(kiocb, 0); | ||
| ]) | ||
| ]) | ||
|
|
||
| AC_DEFUN([ZFS_AC_KERNEL_KIOCB_KI_COMPLETE], [ | ||
| AC_MSG_CHECKING([whether kiocb->ki_complete() wants 2 args]) | ||
| ZFS_LINUX_TEST_RESULT([kiocb_ki_complete_2args], [ | ||
| AC_MSG_RESULT(yes) | ||
| AC_DEFINE(HAVE_2ARGS_KI_COMPLETE, 1, | ||
| [kiocb->ki_complete() wants 2 args]) | ||
| ],[ | ||
| AC_MSG_RESULT(no) | ||
| ]) | ||
| ]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| // SPDX-License-Identifier: CDDL-1.0 | ||
| /* | ||
| * CDDL HEADER START | ||
| * | ||
| * The contents of this file are subject to the terms of the | ||
| * Common Development and Distribution License (the "License"). | ||
| * You may not use this file except in compliance with the License. | ||
| * | ||
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | ||
| * or https://opensource.org/licenses/CDDL-1.0. | ||
| * See the License for the specific language governing permissions | ||
| * and limitations under the License. | ||
| * | ||
| * When distributing Covered Code, include this CDDL HEADER in each | ||
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | ||
| * If applicable, add the following below this CDDL HEADER, with the | ||
| * fields enclosed by brackets "[]" replaced with your own identifying | ||
| * information: Portions Copyright [yyyy] [name of copyright owner] | ||
| * | ||
| * CDDL HEADER END | ||
| * | ||
| * Copyright 2026, tiehexue <tiehexue@hotmail.com>. All rights reserved. | ||
| * | ||
| */ | ||
|
|
||
| #ifndef _SYS_DMU_OS_H | ||
| #define _SYS_DMU_OS_H | ||
|
|
||
| #include <sys/dmu.h> | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| /* | ||
| * Async Direct I/O completion callback type (shared by read and write). | ||
| */ | ||
| typedef void (dmu_abd_done_func_t)(void *arg, int error); | ||
|
|
||
| /* | ||
| * Async Direct I/O read. Submits reads via the ZIO pipeline and returns | ||
| * immediately. The completion callback fires from ZIO taskq context when | ||
| * all reads finish. Caller retains ownership of 'data' until callback. | ||
| */ | ||
| int dmu_read_abd_async(dnode_t *dn, uint64_t offset, uint64_t size, | ||
| abd_t *data, dmu_flags_t flags, | ||
| dmu_abd_done_func_t *done, void *done_arg); | ||
|
|
||
| /* | ||
| * Async Direct I/O write. Submits writes via the ZIO pipeline and returns | ||
| * immediately. The completion callback fires from ZIO taskq context when | ||
| * all writes finish. Caller retains ownership of 'data' until callback | ||
| * and must commit the transaction (tx) from the callback. | ||
| */ | ||
| int dmu_write_abd_async(dnode_t *dn, uint64_t offset, uint64_t size, | ||
| abd_t *data, dmu_flags_t flags, dmu_tx_t *tx, | ||
| dmu_abd_done_func_t *done, void *done_arg); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif /* _SYS_DMU_OS_H */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| // SPDX-License-Identifier: CDDL-1.0 | ||
| /* | ||
| * CDDL HEADER START | ||
| * | ||
| * The contents of this file are subject to the terms of the | ||
| * Common Development and Distribution License (the "License"). | ||
| * You may not use this file except in compliance with the License. | ||
| * | ||
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | ||
| * or https://opensource.org/licenses/CDDL-1.0. | ||
| * See the License for the specific language governing permissions | ||
| * and limitations under the License. | ||
| * | ||
| * When distributing Covered Code, include this CDDL HEADER in each | ||
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | ||
| * If applicable, add the following below this CDDL HEADER, with the | ||
| * fields enclosed by brackets "[]" replaced with your own identifying | ||
| * information: Portions Copyright [yyyy] [name of copyright owner] | ||
| * | ||
| * CDDL HEADER END | ||
| * | ||
| * Copyright 2026, tiehexue <tiehexue@hotmail.com>. All rights reserved. | ||
| * | ||
| */ | ||
|
|
||
| /* | ||
| * Linux async Direct I/O variants for the DMU layer. | ||
| * | ||
| * dmu_read_abd_async() / dmu_write_abd_async() submit I/O via the ZIO | ||
| * pipeline and return immediately. Completions fire from ZIO taskq | ||
| * context via caller-provided callbacks (dmu_abd_done_func_t). | ||
| * | ||
| * These are Linux-only because only the Linux VFS layer has async | ||
| * kiocb / -EIOCBQUEUED infrastructure that benefits from non-blocking | ||
| * DMU entry points. | ||
| */ | ||
|
|
||
| #include <sys/dmu.h> | ||
| #include <sys/dmu_impl.h> | ||
| #include <sys/dmu_direct_os.h> | ||
| #include <sys/dbuf.h> | ||
| #include <sys/dnode.h> | ||
| #include <sys/zfs_context.h> | ||
| #include <sys/zfs_racct.h> | ||
| #include <sys/dsl_dataset.h> | ||
| #include <sys/dmu_objset.h> | ||
|
|
||
| /* | ||
| * Shared async state for dmu_read_abd_async() and dmu_write_abd_async(). | ||
| */ | ||
| struct dmu_abd_async_state { | ||
| dmu_buf_t **ds_dbp; | ||
| int ds_numbufs; | ||
| dmu_abd_done_func_t *ds_done; | ||
| void *ds_done_arg; | ||
| }; | ||
|
|
||
| static void | ||
| dmu_abd_async_done(zio_t *zio) | ||
| { | ||
| struct dmu_abd_async_state *ds = zio->io_private; | ||
| int error = zio->io_error; | ||
|
|
||
| dmu_buf_rele_array(ds->ds_dbp, ds->ds_numbufs, FTAG); | ||
| ds->ds_done(ds->ds_done_arg, error); | ||
| kmem_free(ds, sizeof (*ds)); | ||
| } | ||
|
|
||
| /* | ||
| * Asynchronous variant of dmu_read_abd(). Uses the shared | ||
| * dmu_read_abd_dispatch() helper (common code) for the per-dbuf ZIO | ||
| * submission loop; only the async plumbing (root zio callback, state | ||
| * allocation, zio_nowait) lives here in the Linux-specific layer. | ||
| */ | ||
| int | ||
| dmu_read_abd_async(dnode_t *dn, uint64_t offset, uint64_t size, | ||
| abd_t *data, dmu_flags_t flags, | ||
| dmu_abd_done_func_t *done, void *done_arg) | ||
| { | ||
| spa_t *spa = dn->dn_objset->os_spa; | ||
| dmu_buf_t **dbp; | ||
| int numbufs, err; | ||
|
|
||
| ASSERT(flags & DMU_DIRECTIO); | ||
| ASSERT3P(done, !=, NULL); | ||
|
|
||
| err = dmu_buf_hold_array_by_dnode(dn, offset, | ||
| size, B_FALSE, FTAG, &numbufs, &dbp, flags); | ||
| if (err) | ||
| return (err); | ||
|
|
||
| struct dmu_abd_async_state *ds = | ||
| kmem_alloc(sizeof (*ds), KM_SLEEP); | ||
| ds->ds_dbp = dbp; | ||
| ds->ds_numbufs = numbufs; | ||
| ds->ds_done = done; | ||
| ds->ds_done_arg = done_arg; | ||
|
|
||
| zio_t *rio = zio_root(spa, dmu_abd_async_done, ds, | ||
| ZIO_FLAG_CANFAIL); | ||
|
|
||
| err = dmu_read_abd_dispatch(rio, dn, offset, size, data, flags, | ||
| dbp, numbufs); | ||
|
|
||
| /* | ||
| * Dispatch the root zio. On error, dmu_read_abd_dispatch() has | ||
| * already set rio->io_error; the async done callback will release | ||
| * dbp and signal the caller. | ||
| */ | ||
| zio_nowait(rio); | ||
| return (0); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| /* | ||
| * Asynchronous variant of dmu_write_abd(). Uses the shared | ||
| * dmu_write_abd_dispatch() helper (common code) for the per-dbuf | ||
| * ZIO submission loop; only the async plumbing lives here. | ||
| */ | ||
| int | ||
| dmu_write_abd_async(dnode_t *dn, uint64_t offset, uint64_t size, | ||
| abd_t *data, dmu_flags_t flags, dmu_tx_t *tx, | ||
| dmu_abd_done_func_t *done, void *done_arg) | ||
| { | ||
| spa_t *spa = dn->dn_objset->os_spa; | ||
| dmu_buf_t **dbp; | ||
| int numbufs, err; | ||
|
|
||
| ASSERT(flags & DMU_DIRECTIO); | ||
| ASSERT3P(done, !=, NULL); | ||
|
|
||
| err = dmu_buf_hold_array_by_dnode(dn, offset, | ||
| size, B_FALSE, FTAG, &numbufs, &dbp, flags); | ||
| if (err) | ||
| return (err); | ||
|
|
||
| struct dmu_abd_async_state *ds = | ||
| kmem_alloc(sizeof (*ds), KM_SLEEP); | ||
| ds->ds_dbp = dbp; | ||
| ds->ds_numbufs = numbufs; | ||
| ds->ds_done = done; | ||
| ds->ds_done_arg = done_arg; | ||
|
|
||
| zio_t *pio = zio_root(spa, dmu_abd_async_done, ds, | ||
| ZIO_FLAG_CANFAIL); | ||
|
|
||
| err = dmu_write_abd_dispatch(pio, dn, offset, size, data, flags, tx, | ||
| dbp, numbufs); | ||
|
|
||
| if (err != 0) | ||
| pio->io_error = err; | ||
|
|
||
| zio_nowait(pio); | ||
| return (0); | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.