From: Greg Kroah-Hartman Date: Wed, 10 Mar 2021 12:16:56 +0000 (+0100) Subject: 5.11-stable patches X-Git-Tag: v4.4.261~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a372d0abf58618fb83129ac49d9da3cdc48257b9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.11-stable patches added patches: arm64-make-cpu_big_endian-depend-on-ld.bfd-or-ld.lld-13.0.0.patch btrfs-don-t-flush-from-btrfs_delayed_inode_reserve_metadata.patch btrfs-export-and-rename-qgroup_reserve_meta.patch fs-provide-locked-helper-variant-of-close_fd_get_file.patch io_uring-deduplicate-core-cancellations-sequence.patch io_uring-deduplicate-failing-task_work_add.patch io_uring-don-t-take-uring_lock-during-iowq-cancel.patch io_uring-fix-inconsistent-lock-state.patch io_uring-get-rid-of-intermediate-ioring_op_close-stage.patch io_uring-io-wq-kill-off-now-unused-io_wq_work_no_cancel.patch io_uring-io-wq-return-2-step-work-swap-scheme.patch io_uring-unpark-sqpoll-thread-for-cancelation.patch iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch media-cedrus-remove-checking-for-required-controls.patch nvme-pci-mark-kingston-skc2000-as-not-supporting-the-deepest-power-state.patch parisc-enable-mlong-calls-gcc-option-with-config_compile_test.patch --- diff --git a/queue-5.11/arm64-make-cpu_big_endian-depend-on-ld.bfd-or-ld.lld-13.0.0.patch b/queue-5.11/arm64-make-cpu_big_endian-depend-on-ld.bfd-or-ld.lld-13.0.0.patch new file mode 100644 index 00000000000..f0e4b93a9fe --- /dev/null +++ b/queue-5.11/arm64-make-cpu_big_endian-depend-on-ld.bfd-or-ld.lld-13.0.0.patch @@ -0,0 +1,54 @@ +From foo@baz Wed Mar 10 01:08:03 PM CET 2021 +From: Nathan Chancellor +Date: Mon, 8 Feb 2021 17:57:20 -0700 +Subject: arm64: Make CPU_BIG_ENDIAN depend on ld.bfd or ld.lld 13.0.0+ + +From: Nathan Chancellor + +commit e9c6deee00e9197e75cd6aa0d265d3d45bd7cc28 upstream + +Similar to commit 28187dc8ebd9 ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN +depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly +support aarch64 big endian, leading to the following build error when +CONFIG_CPU_BIG_ENDIAN is selected: + +ld.lld: error: unknown emulation: aarch64linuxb + +This has been resolved in LLVM 13. To avoid errors like this, only allow +CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 +and newer. + +While we are here, the indentation of this symbol used spaces since its +introduction in commit a872013d6d03 ("arm64: kconfig: allow +CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with +kernel coding style. + +Link: https://github.com/ClangBuiltLinux/linux/issues/380 +Link: https://github.com/ClangBuiltLinux/linux/issues/1288 +Link: https://github.com/llvm/llvm-project/commit/7605a9a009b5fa3bdac07e3131c8d82f6d08feb7 +Link: https://github.com/llvm/llvm-project/commit/eea34aae2e74e9b6fbdd5b95f479bc7f397bf387 +Reported-by: Arnd Bergmann +Signed-off-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Link: https://lore.kernel.org/r/20210209005719.803608-1-nathan@kernel.org +Signed-off-by: Will Deacon +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/Kconfig | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -952,8 +952,9 @@ choice + that is selected here. + + config CPU_BIG_ENDIAN +- bool "Build big-endian kernel" +- help ++ bool "Build big-endian kernel" ++ depends on !LD_IS_LLD || LLD_VERSION >= 130000 ++ help + Say Y if you plan on running a kernel with a big-endian userspace. + + config CPU_LITTLE_ENDIAN diff --git a/queue-5.11/btrfs-don-t-flush-from-btrfs_delayed_inode_reserve_metadata.patch b/queue-5.11/btrfs-don-t-flush-from-btrfs_delayed_inode_reserve_metadata.patch new file mode 100644 index 00000000000..2bc95af9200 --- /dev/null +++ b/queue-5.11/btrfs-don-t-flush-from-btrfs_delayed_inode_reserve_metadata.patch @@ -0,0 +1,117 @@ +From foo@baz Wed Mar 10 01:08:03 PM CET 2021 +From: Nikolay Borisov +Date: Mon, 22 Feb 2021 18:40:44 +0200 +Subject: btrfs: don't flush from btrfs_delayed_inode_reserve_metadata + +From: Nikolay Borisov + +commit 4d14c5cde5c268a2bc26addecf09489cb953ef64 upstream + +Calling btrfs_qgroup_reserve_meta_prealloc from +btrfs_delayed_inode_reserve_metadata can result in flushing delalloc +while holding a transaction and delayed node locks. This is deadlock +prone. In the past multiple commits: + + * ae5e070eaca9 ("btrfs: qgroup: don't try to wait flushing if we're +already holding a transaction") + + * 6f23277a49e6 ("btrfs: qgroup: don't commit transaction when we already + hold the handle") + +Tried to solve various aspects of this but this was always a +whack-a-mole game. Unfortunately those 2 fixes don't solve a deadlock +scenario involving btrfs_delayed_node::mutex. Namely, one thread +can call btrfs_dirty_inode as a result of reading a file and modifying +its atime: + + PID: 6963 TASK: ffff8c7f3f94c000 CPU: 2 COMMAND: "test" + #0 __schedule at ffffffffa529e07d + #1 schedule at ffffffffa529e4ff + #2 schedule_timeout at ffffffffa52a1bdd + #3 wait_for_completion at ffffffffa529eeea <-- sleeps with delayed node mutex held + #4 start_delalloc_inodes at ffffffffc0380db5 + #5 btrfs_start_delalloc_snapshot at ffffffffc0393836 + #6 try_flush_qgroup at ffffffffc03f04b2 + #7 __btrfs_qgroup_reserve_meta at ffffffffc03f5bb6 <-- tries to reserve space and starts delalloc inodes. + #8 btrfs_delayed_update_inode at ffffffffc03e31aa <-- acquires delayed node mutex + #9 btrfs_update_inode at ffffffffc0385ba8 + #10 btrfs_dirty_inode at ffffffffc038627b <-- TRANSACTIION OPENED + #11 touch_atime at ffffffffa4cf0000 + #12 generic_file_read_iter at ffffffffa4c1f123 + #13 new_sync_read at ffffffffa4ccdc8a + #14 vfs_read at ffffffffa4cd0849 + #15 ksys_read at ffffffffa4cd0bd1 + #16 do_syscall_64 at ffffffffa4a052eb + #17 entry_SYSCALL_64_after_hwframe at ffffffffa540008c + +This will cause an asynchronous work to flush the delalloc inodes to +happen which can try to acquire the same delayed_node mutex: + + PID: 455 TASK: ffff8c8085fa4000 CPU: 5 COMMAND: "kworker/u16:30" + #0 __schedule at ffffffffa529e07d + #1 schedule at ffffffffa529e4ff + #2 schedule_preempt_disabled at ffffffffa529e80a + #3 __mutex_lock at ffffffffa529fdcb <-- goes to sleep, never wakes up. + #4 btrfs_delayed_update_inode at ffffffffc03e3143 <-- tries to acquire the mutex + #5 btrfs_update_inode at ffffffffc0385ba8 <-- this is the same inode that pid 6963 is holding + #6 cow_file_range_inline.constprop.78 at ffffffffc0386be7 + #7 cow_file_range at ffffffffc03879c1 + #8 btrfs_run_delalloc_range at ffffffffc038894c + #9 writepage_delalloc at ffffffffc03a3c8f + #10 __extent_writepage at ffffffffc03a4c01 + #11 extent_write_cache_pages at ffffffffc03a500b + #12 extent_writepages at ffffffffc03a6de2 + #13 do_writepages at ffffffffa4c277eb + #14 __filemap_fdatawrite_range at ffffffffa4c1e5bb + #15 btrfs_run_delalloc_work at ffffffffc0380987 <-- starts running delayed nodes + #16 normal_work_helper at ffffffffc03b706c + #17 process_one_work at ffffffffa4aba4e4 + #18 worker_thread at ffffffffa4aba6fd + #19 kthread at ffffffffa4ac0a3d + #20 ret_from_fork at ffffffffa54001ff + +To fully address those cases the complete fix is to never issue any +flushing while holding the transaction or the delayed node lock. This +patch achieves it by calling qgroup_reserve_meta directly which will +either succeed without flushing or will fail and return -EDQUOT. In the +latter case that return value is going to be propagated to +btrfs_dirty_inode which will fallback to start a new transaction. That's +fine as the majority of time we expect the inode will have +BTRFS_DELAYED_NODE_INODE_DIRTY flag set which will result in directly +copying the in-memory state. + +Fixes: c53e9653605d ("btrfs: qgroup: try to flush qgroup space when we get -EDQUOT") +CC: stable@vger.kernel.org # 5.10+ +Reviewed-by: Qu Wenruo +Signed-off-by: Nikolay Borisov +Signed-off-by: David Sterba +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/delayed-inode.c | 3 ++- + fs/btrfs/inode.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -627,7 +627,8 @@ static int btrfs_delayed_inode_reserve_m + */ + if (!src_rsv || (!trans->bytes_reserved && + src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) { +- ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true); ++ ret = btrfs_qgroup_reserve_meta(root, num_bytes, ++ BTRFS_QGROUP_RSV_META_PREALLOC, true); + if (ret < 0) + return ret; + ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -5916,7 +5916,7 @@ static int btrfs_dirty_inode(struct inod + return PTR_ERR(trans); + + ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); +- if (ret && ret == -ENOSPC) { ++ if (ret && (ret == -ENOSPC || ret == -EDQUOT)) { + /* whoops, lets try again with the full transaction */ + btrfs_end_transaction(trans); + trans = btrfs_start_transaction(root, 1); diff --git a/queue-5.11/btrfs-export-and-rename-qgroup_reserve_meta.patch b/queue-5.11/btrfs-export-and-rename-qgroup_reserve_meta.patch new file mode 100644 index 00000000000..afed263842c --- /dev/null +++ b/queue-5.11/btrfs-export-and-rename-qgroup_reserve_meta.patch @@ -0,0 +1,60 @@ +From foo@baz Wed Mar 10 01:08:03 PM CET 2021 +From: Nikolay Borisov +Date: Mon, 22 Feb 2021 18:40:43 +0200 +Subject: btrfs: export and rename qgroup_reserve_meta + +From: Nikolay Borisov + +commit 80e9baed722c853056e0c5374f51524593cb1031 upstream + +Signed-off-by: Nikolay Borisov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/qgroup.c | 8 ++++---- + fs/btrfs/qgroup.h | 2 ++ + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -3841,8 +3841,8 @@ static int sub_root_meta_rsv(struct btrf + return num_bytes; + } + +-static int qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, +- enum btrfs_qgroup_rsv_type type, bool enforce) ++int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, ++ enum btrfs_qgroup_rsv_type type, bool enforce) + { + struct btrfs_fs_info *fs_info = root->fs_info; + int ret; +@@ -3873,14 +3873,14 @@ int __btrfs_qgroup_reserve_meta(struct b + { + int ret; + +- ret = qgroup_reserve_meta(root, num_bytes, type, enforce); ++ ret = btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); + if (ret <= 0 && ret != -EDQUOT) + return ret; + + ret = try_flush_qgroup(root); + if (ret < 0) + return ret; +- return qgroup_reserve_meta(root, num_bytes, type, enforce); ++ return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); + } + + void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root) +--- a/fs/btrfs/qgroup.h ++++ b/fs/btrfs/qgroup.h +@@ -361,6 +361,8 @@ int btrfs_qgroup_release_data(struct btr + int btrfs_qgroup_free_data(struct btrfs_inode *inode, + struct extent_changeset *reserved, u64 start, + u64 len); ++int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, ++ enum btrfs_qgroup_rsv_type type, bool enforce); + int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, + enum btrfs_qgroup_rsv_type type, bool enforce); + /* Reserve metadata space for pertrans and prealloc type */ diff --git a/queue-5.11/fs-provide-locked-helper-variant-of-close_fd_get_file.patch b/queue-5.11/fs-provide-locked-helper-variant-of-close_fd_get_file.patch new file mode 100644 index 00000000000..5aa590ab749 --- /dev/null +++ b/queue-5.11/fs-provide-locked-helper-variant-of-close_fd_get_file.patch @@ -0,0 +1,104 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:41 +0000 +Subject: fs: provide locked helper variant of close_fd_get_file() +To: stable@vger.kernel.org +Cc: Jens Axboe +Message-ID: + +From: Jens Axboe + +commit 53dec2ea74f2ef360e8455439be96a780baa6097 upstream + +Assumes current->files->file_lock is already held on invocation. Helps +the caller check the file before removing the fd, if it needs to. + +Signed-off-by: Jens Axboe +Signed-off-by: Pavel Begunkov +Signed-off-by: Greg Kroah-Hartman +--- + fs/file.c | 36 +++++++++++++++++++++++++----------- + fs/internal.h | 1 + + 2 files changed, 26 insertions(+), 11 deletions(-) + +--- a/fs/file.c ++++ b/fs/file.c +@@ -22,6 +22,8 @@ + #include + #include + ++#include "internal.h" ++ + unsigned int sysctl_nr_open __read_mostly = 1024*1024; + unsigned int sysctl_nr_open_min = BITS_PER_LONG; + /* our min() is unusable in constant expressions ;-/ */ +@@ -732,36 +734,48 @@ int __close_range(unsigned fd, unsigned + } + + /* +- * variant of close_fd that gets a ref on the file for later fput. +- * The caller must ensure that filp_close() called on the file, and then +- * an fput(). ++ * See close_fd_get_file() below, this variant assumes current->files->file_lock ++ * is held. + */ +-int close_fd_get_file(unsigned int fd, struct file **res) ++int __close_fd_get_file(unsigned int fd, struct file **res) + { + struct files_struct *files = current->files; + struct file *file; + struct fdtable *fdt; + +- spin_lock(&files->file_lock); + fdt = files_fdtable(files); + if (fd >= fdt->max_fds) +- goto out_unlock; ++ goto out_err; + file = fdt->fd[fd]; + if (!file) +- goto out_unlock; ++ goto out_err; + rcu_assign_pointer(fdt->fd[fd], NULL); + __put_unused_fd(files, fd); +- spin_unlock(&files->file_lock); + get_file(file); + *res = file; + return 0; +- +-out_unlock: +- spin_unlock(&files->file_lock); ++out_err: + *res = NULL; + return -ENOENT; + } + ++/* ++ * variant of close_fd that gets a ref on the file for later fput. ++ * The caller must ensure that filp_close() called on the file, and then ++ * an fput(). ++ */ ++int close_fd_get_file(unsigned int fd, struct file **res) ++{ ++ struct files_struct *files = current->files; ++ int ret; ++ ++ spin_lock(&files->file_lock); ++ ret = __close_fd_get_file(fd, res); ++ spin_unlock(&files->file_lock); ++ ++ return ret; ++} ++ + void do_close_on_exec(struct files_struct *files) + { + unsigned i; +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -132,6 +132,7 @@ extern struct file *do_file_open_root(st + const char *, const struct open_flags *); + extern struct open_how build_open_how(int flags, umode_t mode); + extern int build_open_flags(const struct open_how *how, struct open_flags *op); ++extern int __close_fd_get_file(unsigned int fd, struct file **res); + + long do_sys_ftruncate(unsigned int fd, loff_t length, int small); + int chmod_common(const struct path *path, umode_t mode); diff --git a/queue-5.11/io_uring-deduplicate-core-cancellations-sequence.patch b/queue-5.11/io_uring-deduplicate-core-cancellations-sequence.patch new file mode 100644 index 00000000000..1b3778afeb0 --- /dev/null +++ b/queue-5.11/io_uring-deduplicate-core-cancellations-sequence.patch @@ -0,0 +1,165 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:38 +0000 +Subject: io_uring: deduplicate core cancellations sequence +To: stable@vger.kernel.org +Cc: Jens Axboe +Message-ID: + +From: Pavel Begunkov + +commit 9936c7c2bc76a0b2276f6d19de6d1d92f03deeab upstream + +Files and task cancellations go over same steps trying to cancel +requests in io-wq, poll, etc. Deduplicate it with a helper. + +note: new io_uring_try_cancel_requests() is former +__io_uring_cancel_task_requests() with files passed as an agrument and +flushing overflowed requests. + +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 85 +++++++++++++++++++++++++++------------------------------- + 1 file changed, 40 insertions(+), 45 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -996,9 +996,9 @@ enum io_mem_account { + ACCT_PINNED, + }; + +-static void __io_uring_cancel_task_requests(struct io_ring_ctx *ctx, +- struct task_struct *task); +- ++static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, ++ struct task_struct *task, ++ struct files_struct *files); + static void destroy_fixed_file_ref_node(struct fixed_file_ref_node *ref_node); + static struct fixed_file_ref_node *alloc_fixed_file_ref_node( + struct io_ring_ctx *ctx); +@@ -8780,7 +8780,7 @@ static void io_ring_exit_work(struct wor + * as nobody else will be looking for them. + */ + do { +- __io_uring_cancel_task_requests(ctx, NULL); ++ io_uring_try_cancel_requests(ctx, NULL, NULL); + } while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20)); + io_ring_ctx_free(ctx); + } +@@ -8894,6 +8894,40 @@ static void io_cancel_defer_files(struct + } + } + ++static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, ++ struct task_struct *task, ++ struct files_struct *files) ++{ ++ struct io_task_cancel cancel = { .task = task, .files = files, }; ++ ++ while (1) { ++ enum io_wq_cancel cret; ++ bool ret = false; ++ ++ if (ctx->io_wq) { ++ cret = io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, ++ &cancel, true); ++ ret |= (cret != IO_WQ_CANCEL_NOTFOUND); ++ } ++ ++ /* SQPOLL thread does its own polling */ ++ if (!(ctx->flags & IORING_SETUP_SQPOLL) && !files) { ++ while (!list_empty_careful(&ctx->iopoll_list)) { ++ io_iopoll_try_reap_events(ctx); ++ ret = true; ++ } ++ } ++ ++ ret |= io_poll_remove_all(ctx, task, files); ++ ret |= io_kill_timeouts(ctx, task, files); ++ ret |= io_run_task_work(); ++ io_cqring_overflow_flush(ctx, true, task, files); ++ if (!ret) ++ break; ++ cond_resched(); ++ } ++} ++ + static int io_uring_count_inflight(struct io_ring_ctx *ctx, + struct task_struct *task, + struct files_struct *files) +@@ -8913,7 +8947,6 @@ static void io_uring_cancel_files(struct + struct files_struct *files) + { + while (!list_empty_careful(&ctx->inflight_list)) { +- struct io_task_cancel cancel = { .task = task, .files = files }; + DEFINE_WAIT(wait); + int inflight; + +@@ -8921,13 +8954,7 @@ static void io_uring_cancel_files(struct + if (!inflight) + break; + +- io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, &cancel, true); +- io_poll_remove_all(ctx, task, files); +- io_kill_timeouts(ctx, task, files); +- io_cqring_overflow_flush(ctx, true, task, files); +- /* cancellations _may_ trigger task work */ +- io_run_task_work(); +- ++ io_uring_try_cancel_requests(ctx, task, files); + prepare_to_wait(&task->io_uring->wait, &wait, + TASK_UNINTERRUPTIBLE); + if (inflight == io_uring_count_inflight(ctx, task, files)) +@@ -8936,37 +8963,6 @@ static void io_uring_cancel_files(struct + } + } + +-static void __io_uring_cancel_task_requests(struct io_ring_ctx *ctx, +- struct task_struct *task) +-{ +- while (1) { +- struct io_task_cancel cancel = { .task = task, .files = NULL, }; +- enum io_wq_cancel cret; +- bool ret = false; +- +- if (ctx->io_wq) { +- cret = io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, +- &cancel, true); +- ret |= (cret != IO_WQ_CANCEL_NOTFOUND); +- } +- +- /* SQPOLL thread does its own polling */ +- if (!(ctx->flags & IORING_SETUP_SQPOLL)) { +- while (!list_empty_careful(&ctx->iopoll_list)) { +- io_iopoll_try_reap_events(ctx); +- ret = true; +- } +- } +- +- ret |= io_poll_remove_all(ctx, task, NULL); +- ret |= io_kill_timeouts(ctx, task, NULL); +- ret |= io_run_task_work(); +- if (!ret) +- break; +- cond_resched(); +- } +-} +- + static void io_disable_sqo_submit(struct io_ring_ctx *ctx) + { + mutex_lock(&ctx->uring_lock); +@@ -8996,11 +8992,10 @@ static void io_uring_cancel_task_request + } + + io_cancel_defer_files(ctx, task, files); +- io_cqring_overflow_flush(ctx, true, task, files); + + io_uring_cancel_files(ctx, task, files); + if (!files) +- __io_uring_cancel_task_requests(ctx, task); ++ io_uring_try_cancel_requests(ctx, task, NULL); + + if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { + atomic_dec(&task->io_uring->in_idle); diff --git a/queue-5.11/io_uring-deduplicate-failing-task_work_add.patch b/queue-5.11/io_uring-deduplicate-failing-task_work_add.patch new file mode 100644 index 00000000000..ab3db72c8ab --- /dev/null +++ b/queue-5.11/io_uring-deduplicate-failing-task_work_add.patch @@ -0,0 +1,106 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:40 +0000 +Subject: io_uring: deduplicate failing task_work_add +To: stable@vger.kernel.org +Cc: Jens Axboe +Message-ID: <5ad81cd57c41877a4667ea8dd5397987af6cce41.1615375332.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +commit eab30c4d20dc761d463445e5130421863ff81505 upstream + +When io_req_task_work_add() fails, the request will be cancelled by +enqueueing via task_works of io-wq. Extract a function for that. + +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 46 +++++++++++++++++----------------------------- + 1 file changed, 17 insertions(+), 29 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2172,6 +2172,16 @@ static int io_req_task_work_add(struct i + return ret; + } + ++static void io_req_task_work_add_fallback(struct io_kiocb *req, ++ void (*cb)(struct callback_head *)) ++{ ++ struct task_struct *tsk = io_wq_get_task(req->ctx->io_wq); ++ ++ init_task_work(&req->task_work, cb); ++ task_work_add(tsk, &req->task_work, TWA_NONE); ++ wake_up_process(tsk); ++} ++ + static void __io_req_task_cancel(struct io_kiocb *req, int error) + { + struct io_ring_ctx *ctx = req->ctx; +@@ -2229,14 +2239,8 @@ static void io_req_task_queue(struct io_ + percpu_ref_get(&req->ctx->refs); + + ret = io_req_task_work_add(req); +- if (unlikely(ret)) { +- struct task_struct *tsk; +- +- init_task_work(&req->task_work, io_req_task_cancel); +- tsk = io_wq_get_task(req->ctx->io_wq); +- task_work_add(tsk, &req->task_work, TWA_NONE); +- wake_up_process(tsk); +- } ++ if (unlikely(ret)) ++ io_req_task_work_add_fallback(req, io_req_task_cancel); + } + + static inline void io_queue_next(struct io_kiocb *req) +@@ -2354,13 +2358,8 @@ static void io_free_req_deferred(struct + + init_task_work(&req->task_work, io_put_req_deferred_cb); + ret = io_req_task_work_add(req); +- if (unlikely(ret)) { +- struct task_struct *tsk; +- +- tsk = io_wq_get_task(req->ctx->io_wq); +- task_work_add(tsk, &req->task_work, TWA_NONE); +- wake_up_process(tsk); +- } ++ if (unlikely(ret)) ++ io_req_task_work_add_fallback(req, io_put_req_deferred_cb); + } + + static inline void io_put_req_deferred(struct io_kiocb *req, int refs) +@@ -3439,15 +3438,8 @@ static int io_async_buf_func(struct wait + /* submit ref gets dropped, acquire a new one */ + refcount_inc(&req->refs); + ret = io_req_task_work_add(req); +- if (unlikely(ret)) { +- struct task_struct *tsk; +- +- /* queue just for cancelation */ +- init_task_work(&req->task_work, io_req_task_cancel); +- tsk = io_wq_get_task(req->ctx->io_wq); +- task_work_add(tsk, &req->task_work, TWA_NONE); +- wake_up_process(tsk); +- } ++ if (unlikely(ret)) ++ io_req_task_work_add_fallback(req, io_req_task_cancel); + return 1; + } + +@@ -5159,12 +5151,8 @@ static int __io_async_wake(struct io_kio + */ + ret = io_req_task_work_add(req); + if (unlikely(ret)) { +- struct task_struct *tsk; +- + WRITE_ONCE(poll->canceled, true); +- tsk = io_wq_get_task(req->ctx->io_wq); +- task_work_add(tsk, &req->task_work, TWA_NONE); +- wake_up_process(tsk); ++ io_req_task_work_add_fallback(req, func); + } + return 1; + } diff --git a/queue-5.11/io_uring-don-t-take-uring_lock-during-iowq-cancel.patch b/queue-5.11/io_uring-don-t-take-uring_lock-during-iowq-cancel.patch new file mode 100644 index 00000000000..f845c706471 --- /dev/null +++ b/queue-5.11/io_uring-don-t-take-uring_lock-during-iowq-cancel.patch @@ -0,0 +1,97 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:45 +0000 +Subject: io_uring: don't take uring_lock during iowq cancel +To: stable@vger.kernel.org +Cc: Jens Axboe , Abaci , Hao Xu +Message-ID: <1839646480a26a2461eccc38a75e98998d2d6e11.1615375332.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +commit 792bb6eb862333658bf1bd2260133f0507e2da8d upstream + +[ 97.866748] a.out/2890 is trying to acquire lock: +[ 97.867829] ffff8881046763e8 (&ctx->uring_lock){+.+.}-{3:3}, at: +io_wq_submit_work+0x155/0x240 +[ 97.869735] +[ 97.869735] but task is already holding lock: +[ 97.871033] ffff88810dfe0be8 (&ctx->uring_lock){+.+.}-{3:3}, at: +__x64_sys_io_uring_enter+0x3f0/0x5b0 +[ 97.873074] +[ 97.873074] other info that might help us debug this: +[ 97.874520] Possible unsafe locking scenario: +[ 97.874520] +[ 97.875845] CPU0 +[ 97.876440] ---- +[ 97.877048] lock(&ctx->uring_lock); +[ 97.877961] lock(&ctx->uring_lock); +[ 97.878881] +[ 97.878881] *** DEADLOCK *** +[ 97.878881] +[ 97.880341] May be due to missing lock nesting notation +[ 97.880341] +[ 97.881952] 1 lock held by a.out/2890: +[ 97.882873] #0: ffff88810dfe0be8 (&ctx->uring_lock){+.+.}-{3:3}, at: +__x64_sys_io_uring_enter+0x3f0/0x5b0 +[ 97.885108] +[ 97.885108] stack backtrace: +[ 97.890457] Call Trace: +[ 97.891121] dump_stack+0xac/0xe3 +[ 97.891972] __lock_acquire+0xab6/0x13a0 +[ 97.892940] lock_acquire+0x2c3/0x390 +[ 97.894894] __mutex_lock+0xae/0x9f0 +[ 97.901101] io_wq_submit_work+0x155/0x240 +[ 97.902112] io_wq_cancel_cb+0x162/0x490 +[ 97.904126] io_async_find_and_cancel+0x3b/0x140 +[ 97.905247] io_issue_sqe+0x86d/0x13e0 +[ 97.909122] __io_queue_sqe+0x10b/0x550 +[ 97.913971] io_queue_sqe+0x235/0x470 +[ 97.914894] io_submit_sqes+0xcce/0xf10 +[ 97.917872] __x64_sys_io_uring_enter+0x3fb/0x5b0 +[ 97.921424] do_syscall_64+0x2d/0x40 +[ 97.922329] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +While holding uring_lock, e.g. from inline execution, async cancel +request may attempt cancellations through io_wq_submit_work, which may +try to grab a lock. Delay it to task_work, so we do it from a clean +context and don't have to worry about locking. + +Cc: # 5.5+ +Fixes: c07e6719511e ("io_uring: hold uring_lock while completing failed polled io in io_wq_submit_work()") +Reported-by: Abaci +Reported-by: Hao Xu +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2198,7 +2198,9 @@ static void io_req_task_cancel(struct ca + struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work); + struct io_ring_ctx *ctx = req->ctx; + ++ mutex_lock(&ctx->uring_lock); + __io_req_task_cancel(req, -ECANCELED); ++ mutex_unlock(&ctx->uring_lock); + percpu_ref_put(&ctx->refs); + } + +@@ -6372,8 +6374,13 @@ static void io_wq_submit_work(struct io_ + if (timeout) + io_queue_linked_timeout(timeout); + +- if (work->flags & IO_WQ_WORK_CANCEL) +- ret = -ECANCELED; ++ if (work->flags & IO_WQ_WORK_CANCEL) { ++ /* io-wq is going to take down one */ ++ refcount_inc(&req->refs); ++ percpu_ref_get(&req->ctx->refs); ++ io_req_task_work_add_fallback(req, io_req_task_cancel); ++ return; ++ } + + if (!ret) { + do { diff --git a/queue-5.11/io_uring-fix-inconsistent-lock-state.patch b/queue-5.11/io_uring-fix-inconsistent-lock-state.patch new file mode 100644 index 00000000000..c09ed047435 --- /dev/null +++ b/queue-5.11/io_uring-fix-inconsistent-lock-state.patch @@ -0,0 +1,100 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:37 +0000 +Subject: io_uring: fix inconsistent lock state +To: stable@vger.kernel.org +Cc: Jens Axboe , syzbot+81d17233a2b02eafba33@syzkaller.appspotmail.com +Message-ID: <780db85414287452e1c4d208b2a1920760cad721.1615375332.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +commin 9ae1f8dd372e0e4c020b345cf9e09f519265e981 upstream + +WARNING: inconsistent lock state + +inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +syz-executor217/8450 [HC1[1]:SC0[0]:HE0:SE1] takes: +ffff888023d6e620 (&fs->lock){?.+.}-{2:2}, at: spin_lock include/linux/spinlock.h:354 [inline] +ffff888023d6e620 (&fs->lock){?.+.}-{2:2}, at: io_req_clean_work fs/io_uring.c:1398 [inline] +ffff888023d6e620 (&fs->lock){?.+.}-{2:2}, at: io_dismantle_req+0x66f/0xf60 fs/io_uring.c:2029 + +other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(&fs->lock); + + lock(&fs->lock); + + *** DEADLOCK *** + +1 lock held by syz-executor217/8450: + #0: ffff88802417c3e8 (&ctx->uring_lock){+.+.}-{3:3}, at: __do_sys_io_uring_enter+0x1071/0x1f30 fs/io_uring.c:9442 + +stack backtrace: +CPU: 1 PID: 8450 Comm: syz-executor217 Not tainted 5.11.0-rc5-next-20210129-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + +[...] + _raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:151 + spin_lock include/linux/spinlock.h:354 [inline] + io_req_clean_work fs/io_uring.c:1398 [inline] + io_dismantle_req+0x66f/0xf60 fs/io_uring.c:2029 + __io_free_req+0x3d/0x2e0 fs/io_uring.c:2046 + io_free_req fs/io_uring.c:2269 [inline] + io_double_put_req fs/io_uring.c:2392 [inline] + io_put_req+0xf9/0x570 fs/io_uring.c:2388 + io_link_timeout_fn+0x30c/0x480 fs/io_uring.c:6497 + __run_hrtimer kernel/time/hrtimer.c:1519 [inline] + __hrtimer_run_queues+0x609/0xe40 kernel/time/hrtimer.c:1583 + hrtimer_interrupt+0x334/0x940 kernel/time/hrtimer.c:1645 + local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1085 [inline] + __sysvec_apic_timer_interrupt+0x146/0x540 arch/x86/kernel/apic/apic.c:1102 + asm_call_irq_on_stack+0xf/0x20 + + __run_sysvec_on_irqstack arch/x86/include/asm/irq_stack.h:37 [inline] + run_sysvec_on_irqstack_cond arch/x86/include/asm/irq_stack.h:89 [inline] + sysvec_apic_timer_interrupt+0xbd/0x100 arch/x86/kernel/apic/apic.c:1096 + asm_sysvec_apic_timer_interrupt+0x12/0x20 arch/x86/include/asm/idtentry.h:629 +RIP: 0010:__raw_spin_unlock_irq include/linux/spinlock_api_smp.h:169 [inline] +RIP: 0010:_raw_spin_unlock_irq+0x25/0x40 kernel/locking/spinlock.c:199 + spin_unlock_irq include/linux/spinlock.h:404 [inline] + io_queue_linked_timeout+0x194/0x1f0 fs/io_uring.c:6525 + __io_queue_sqe+0x328/0x1290 fs/io_uring.c:6594 + io_queue_sqe+0x631/0x10d0 fs/io_uring.c:6639 + io_queue_link_head fs/io_uring.c:6650 [inline] + io_submit_sqe fs/io_uring.c:6697 [inline] + io_submit_sqes+0x19b5/0x2720 fs/io_uring.c:6960 + __do_sys_io_uring_enter+0x107d/0x1f30 fs/io_uring.c:9443 + do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Don't free requests from under hrtimer context (softirq) as it may sleep +or take spinlocks improperly (e.g. non-irq versions). + +Cc: stable@vger.kernel.org # 5.6+ +Reported-by: syzbot+81d17233a2b02eafba33@syzkaller.appspotmail.com +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -6506,9 +6506,10 @@ static enum hrtimer_restart io_link_time + if (prev) { + req_set_fail_links(prev); + io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME); +- io_put_req(prev); ++ io_put_req_deferred(prev, 1); + } else { +- io_req_complete(req, -ETIME); ++ io_cqring_add_event(req, -ETIME, 0); ++ io_put_req_deferred(req, 1); + } + return HRTIMER_NORESTART; + } diff --git a/queue-5.11/io_uring-get-rid-of-intermediate-ioring_op_close-stage.patch b/queue-5.11/io_uring-get-rid-of-intermediate-ioring_op_close-stage.patch new file mode 100644 index 00000000000..e2e9f2e3aba --- /dev/null +++ b/queue-5.11/io_uring-get-rid-of-intermediate-ioring_op_close-stage.patch @@ -0,0 +1,141 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:42 +0000 +Subject: io_uring: get rid of intermediate IORING_OP_CLOSE stage +To: stable@vger.kernel.org +Cc: Jens Axboe +Message-ID: <89cbacd2635e9e91db0139cf2d3906621afa399a.1615375332.git.asml.silence@gmail.com> + +From: Jens Axboe + +commit 9eac1904d3364254d622bf2c771c4f85cd435fc2 upstream + +We currently split the close into two, in case we have a ->flush op +that we can't safely handle from non-blocking context. This requires +us to flag the op as uncancelable if we do need to punt it async, and +that means special handling for just this op type. + +Use __close_fd_get_file() and grab the files lock so we can get the file +and check if we need to go async in one atomic operation. That gets rid +of the need for splitting this into two steps, and hence the need for +IO_WQ_WORK_NO_CANCEL. + +Signed-off-by: Jens Axboe +Signed-off-by: Pavel Begunkov +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 64 +++++++++++++++++++++++++++++++--------------------------- + 1 file changed, 35 insertions(+), 29 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -411,7 +411,6 @@ struct io_poll_remove { + + struct io_close { + struct file *file; +- struct file *put_file; + int fd; + }; + +@@ -908,8 +907,6 @@ static const struct io_op_def io_op_defs + IO_WQ_WORK_FS | IO_WQ_WORK_MM, + }, + [IORING_OP_CLOSE] = { +- .needs_file = 1, +- .needs_file_no_error = 1, + .work_flags = IO_WQ_WORK_FILES | IO_WQ_WORK_BLKCG, + }, + [IORING_OP_FILES_UPDATE] = { +@@ -4473,13 +4470,6 @@ static int io_statx(struct io_kiocb *req + + static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) + { +- /* +- * If we queue this for async, it must not be cancellable. That would +- * leave the 'file' in an undeterminate state, and here need to modify +- * io_wq_work.flags, so initialize io_wq_work firstly. +- */ +- io_req_init_async(req); +- + if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) + return -EINVAL; + if (sqe->ioprio || sqe->off || sqe->addr || sqe->len || +@@ -4489,43 +4479,59 @@ static int io_close_prep(struct io_kiocb + return -EBADF; + + req->close.fd = READ_ONCE(sqe->fd); +- if ((req->file && req->file->f_op == &io_uring_fops)) +- return -EBADF; +- +- req->close.put_file = NULL; + return 0; + } + + static int io_close(struct io_kiocb *req, bool force_nonblock, + struct io_comp_state *cs) + { ++ struct files_struct *files = current->files; + struct io_close *close = &req->close; ++ struct fdtable *fdt; ++ struct file *file; + int ret; + +- /* might be already done during nonblock submission */ +- if (!close->put_file) { +- ret = close_fd_get_file(close->fd, &close->put_file); +- if (ret < 0) +- return (ret == -ENOENT) ? -EBADF : ret; ++ file = NULL; ++ ret = -EBADF; ++ spin_lock(&files->file_lock); ++ fdt = files_fdtable(files); ++ if (close->fd >= fdt->max_fds) { ++ spin_unlock(&files->file_lock); ++ goto err; ++ } ++ file = fdt->fd[close->fd]; ++ if (!file) { ++ spin_unlock(&files->file_lock); ++ goto err; ++ } ++ ++ if (file->f_op == &io_uring_fops) { ++ spin_unlock(&files->file_lock); ++ file = NULL; ++ goto err; + } + + /* if the file has a flush method, be safe and punt to async */ +- if (close->put_file->f_op->flush && force_nonblock) { +- /* not safe to cancel at this point */ +- req->work.flags |= IO_WQ_WORK_NO_CANCEL; +- /* was never set, but play safe */ +- req->flags &= ~REQ_F_NOWAIT; +- /* avoid grabbing files - we don't need the files */ +- req->flags |= REQ_F_NO_FILE_TABLE; ++ if (file->f_op->flush && force_nonblock) { ++ spin_unlock(&files->file_lock); + return -EAGAIN; + } + ++ ret = __close_fd_get_file(close->fd, &file); ++ spin_unlock(&files->file_lock); ++ if (ret < 0) { ++ if (ret == -ENOENT) ++ ret = -EBADF; ++ goto err; ++ } ++ + /* No ->flush() or already async, safely close from here */ +- ret = filp_close(close->put_file, req->work.identity->files); ++ ret = filp_close(file, current->files); ++err: + if (ret < 0) + req_set_fail_links(req); +- fput(close->put_file); +- close->put_file = NULL; ++ if (file) ++ fput(file); + __io_req_complete(req, ret, 0, cs); + return 0; + } diff --git a/queue-5.11/io_uring-io-wq-kill-off-now-unused-io_wq_work_no_cancel.patch b/queue-5.11/io_uring-io-wq-kill-off-now-unused-io_wq_work_no_cancel.patch new file mode 100644 index 00000000000..59083a281cf --- /dev/null +++ b/queue-5.11/io_uring-io-wq-kill-off-now-unused-io_wq_work_no_cancel.patch @@ -0,0 +1,59 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:43 +0000 +Subject: io_uring/io-wq: kill off now unused IO_WQ_WORK_NO_CANCEL +To: stable@vger.kernel.org +Cc: Jens Axboe +Message-ID: <0a53f04021951888af40f5e487d593c4ac39b244.1615375332.git.asml.silence@gmail.com> + +From: Jens Axboe + +commit 4014d943cb62db892eb023d385a966a3fce5ee4c upstream + +It's no longer used as IORING_OP_CLOSE got rid for the need of flagging +it as uncancelable, kill it of. + +Signed-off-by: Jens Axboe +Signed-off-by: Pavel Begunkov +Signed-off-by: Greg Kroah-Hartman +--- + fs/io-wq.c | 1 - + fs/io-wq.h | 1 - + fs/io_uring.c | 5 +---- + 3 files changed, 1 insertion(+), 6 deletions(-) + +--- a/fs/io-wq.c ++++ b/fs/io-wq.c +@@ -944,7 +944,6 @@ static bool io_wq_worker_cancel(struct i + */ + spin_lock_irqsave(&worker->lock, flags); + if (worker->cur_work && +- !(worker->cur_work->flags & IO_WQ_WORK_NO_CANCEL) && + match->fn(worker->cur_work, match->data)) { + send_sig(SIGINT, worker->task, 1); + match->nr_running++; +--- a/fs/io-wq.h ++++ b/fs/io-wq.h +@@ -9,7 +9,6 @@ enum { + IO_WQ_WORK_CANCEL = 1, + IO_WQ_WORK_HASHED = 2, + IO_WQ_WORK_UNBOUND = 4, +- IO_WQ_WORK_NO_CANCEL = 8, + IO_WQ_WORK_CONCURRENT = 16, + + IO_WQ_WORK_FILES = 32, +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -6388,11 +6388,8 @@ static struct io_wq_work *io_wq_submit_w + if (timeout) + io_queue_linked_timeout(timeout); + +- /* if NO_CANCEL is set, we must still run the work */ +- if ((work->flags & (IO_WQ_WORK_CANCEL|IO_WQ_WORK_NO_CANCEL)) == +- IO_WQ_WORK_CANCEL) { ++ if (work->flags & IO_WQ_WORK_CANCEL) + ret = -ECANCELED; +- } + + if (!ret) { + do { diff --git a/queue-5.11/io_uring-io-wq-return-2-step-work-swap-scheme.patch b/queue-5.11/io_uring-io-wq-return-2-step-work-swap-scheme.patch new file mode 100644 index 00000000000..eb2c9fea526 --- /dev/null +++ b/queue-5.11/io_uring-io-wq-return-2-step-work-swap-scheme.patch @@ -0,0 +1,144 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:44 +0000 +Subject: io_uring/io-wq: return 2-step work swap scheme +To: stable@vger.kernel.org +Cc: Jens Axboe +Message-ID: <506ec0ce0b991836bb5132840fd1889126c86c8e.1615375332.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +commit 5280f7e530f71ba85baf90169393196976ad0e52 upstream + +Saving one lock/unlock for io-wq is not super important, but adds some +ugliness in the code. More important, atomic decs not turning it to zero +for some archs won't give the right ordering/barriers so the +io_steal_work() may pretty easily get subtly and completely broken. + +Return back 2-step io-wq work exchange and clean it up. + +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io-wq.c | 16 ++++++---------- + fs/io-wq.h | 4 ++-- + fs/io_uring.c | 26 ++++---------------------- + 3 files changed, 12 insertions(+), 34 deletions(-) + +--- a/fs/io-wq.c ++++ b/fs/io-wq.c +@@ -555,23 +555,21 @@ get_next: + + /* handle a whole dependent link */ + do { +- struct io_wq_work *old_work, *next_hashed, *linked; ++ struct io_wq_work *next_hashed, *linked; + unsigned int hash = io_get_work_hash(work); + + next_hashed = wq_next_work(work); + io_impersonate_work(worker, work); ++ wq->do_work(work); ++ io_assign_current_work(worker, NULL); + +- old_work = work; +- linked = wq->do_work(work); +- ++ linked = wq->free_work(work); + work = next_hashed; + if (!work && linked && !io_wq_is_hashed(linked)) { + work = linked; + linked = NULL; + } + io_assign_current_work(worker, work); +- wq->free_work(old_work); +- + if (linked) + io_wqe_enqueue(wqe, linked); + +@@ -850,11 +848,9 @@ static void io_run_cancel(struct io_wq_w + struct io_wq *wq = wqe->wq; + + do { +- struct io_wq_work *old_work = work; +- + work->flags |= IO_WQ_WORK_CANCEL; +- work = wq->do_work(work); +- wq->free_work(old_work); ++ wq->do_work(work); ++ work = wq->free_work(work); + } while (work); + } + +--- a/fs/io-wq.h ++++ b/fs/io-wq.h +@@ -106,8 +106,8 @@ static inline struct io_wq_work *wq_next + return container_of(work->list.next, struct io_wq_work, list); + } + +-typedef void (free_work_fn)(struct io_wq_work *); +-typedef struct io_wq_work *(io_wq_work_fn)(struct io_wq_work *); ++typedef struct io_wq_work *(free_work_fn)(struct io_wq_work *); ++typedef void (io_wq_work_fn)(struct io_wq_work *); + + struct io_wq_data { + struct user_struct *user; +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2365,22 +2365,6 @@ static inline void io_put_req_deferred(s + io_free_req_deferred(req); + } + +-static struct io_wq_work *io_steal_work(struct io_kiocb *req) +-{ +- struct io_kiocb *nxt; +- +- /* +- * A ref is owned by io-wq in which context we're. So, if that's the +- * last one, it's safe to steal next work. False negatives are Ok, +- * it just will be re-punted async in io_put_work() +- */ +- if (refcount_read(&req->refs) != 1) +- return NULL; +- +- nxt = io_req_find_next(req); +- return nxt ? &nxt->work : NULL; +-} +- + static void io_double_put_req(struct io_kiocb *req) + { + /* drop both submit and complete references */ +@@ -6378,7 +6362,7 @@ static int io_issue_sqe(struct io_kiocb + return 0; + } + +-static struct io_wq_work *io_wq_submit_work(struct io_wq_work *work) ++static void io_wq_submit_work(struct io_wq_work *work) + { + struct io_kiocb *req = container_of(work, struct io_kiocb, work); + struct io_kiocb *timeout; +@@ -6429,8 +6413,6 @@ static struct io_wq_work *io_wq_submit_w + if (lock_ctx) + mutex_unlock(&lock_ctx->uring_lock); + } +- +- return io_steal_work(req); + } + + static inline struct file *io_file_from_index(struct io_ring_ctx *ctx, +@@ -8062,12 +8044,12 @@ static int io_sqe_files_update(struct io + return __io_sqe_files_update(ctx, &up, nr_args); + } + +-static void io_free_work(struct io_wq_work *work) ++static struct io_wq_work *io_free_work(struct io_wq_work *work) + { + struct io_kiocb *req = container_of(work, struct io_kiocb, work); + +- /* Consider that io_steal_work() relies on this ref */ +- io_put_req(req); ++ req = io_put_req_find_next(req); ++ return req ? &req->work : NULL; + } + + static int io_init_wq_offload(struct io_ring_ctx *ctx, diff --git a/queue-5.11/io_uring-unpark-sqpoll-thread-for-cancelation.patch b/queue-5.11/io_uring-unpark-sqpoll-thread-for-cancelation.patch new file mode 100644 index 00000000000..3ea6ac23dd2 --- /dev/null +++ b/queue-5.11/io_uring-unpark-sqpoll-thread-for-cancelation.patch @@ -0,0 +1,65 @@ +From foo@baz Wed Mar 10 01:03:15 PM CET 2021 +From: Pavel Begunkov +Date: Wed, 10 Mar 2021 11:30:39 +0000 +Subject: io_uring: unpark SQPOLL thread for cancelation +To: stable@vger.kernel.org +Cc: Jens Axboe , syzbot+695b03d82fa8e4901b06@syzkaller.appspotmail.com +Message-ID: <165b3785cd6e17ffea1e53dfab027b6f89684dde.1615375332.git.asml.silence@gmail.com> + +From: Pavel Begunkov + +commit 34343786ecc5ff493ca4d1f873b4386759ba52ee upstream + +We park SQPOLL task before going into io_uring_cancel_files(), so the +task won't run task_works including those that might be important for +the cancellation passes. In this case it's io_poll_remove_one(), which +frees requests via io_put_req_deferred(). + +Unpark it for while waiting, it's ok as we disable submissions +beforehand, so no new requests will be generated. + +INFO: task syz-executor893:8493 blocked for more than 143 seconds. +Call Trace: + context_switch kernel/sched/core.c:4327 [inline] + __schedule+0x90c/0x21a0 kernel/sched/core.c:5078 + schedule+0xcf/0x270 kernel/sched/core.c:5157 + io_uring_cancel_files fs/io_uring.c:8912 [inline] + io_uring_cancel_task_requests+0xe70/0x11a0 fs/io_uring.c:8979 + __io_uring_files_cancel+0x110/0x1b0 fs/io_uring.c:9067 + io_uring_files_cancel include/linux/io_uring.h:51 [inline] + do_exit+0x2fe/0x2ae0 kernel/exit.c:780 + do_group_exit+0x125/0x310 kernel/exit.c:922 + __do_sys_exit_group kernel/exit.c:933 [inline] + __se_sys_exit_group kernel/exit.c:931 [inline] + __x64_sys_exit_group+0x3a/0x50 kernel/exit.c:931 + do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Cc: stable@vger.kernel.org # 5.5+ +Reported-by: syzbot+695b03d82fa8e4901b06@syzkaller.appspotmail.com +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -8955,11 +8955,16 @@ static void io_uring_cancel_files(struct + break; + + io_uring_try_cancel_requests(ctx, task, files); ++ ++ if (ctx->sq_data) ++ io_sq_thread_unpark(ctx->sq_data); + prepare_to_wait(&task->io_uring->wait, &wait, + TASK_UNINTERRUPTIBLE); + if (inflight == io_uring_count_inflight(ctx, task, files)) + schedule(); + finish_wait(&task->io_uring->wait, &wait); ++ if (ctx->sq_data) ++ io_sq_thread_park(ctx->sq_data); + } + } + diff --git a/queue-5.11/iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch b/queue-5.11/iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch new file mode 100644 index 00000000000..9fcd38935c1 --- /dev/null +++ b/queue-5.11/iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch @@ -0,0 +1,83 @@ +From 140456f994195b568ecd7fc2287a34eadffef3ca Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Wed, 17 Feb 2021 17:30:04 +0300 +Subject: iommu/amd: Fix sleeping in atomic in increase_address_space() + +From: Andrey Ryabinin + +commit 140456f994195b568ecd7fc2287a34eadffef3ca upstream. + +increase_address_space() calls get_zeroed_page(gfp) under spin_lock with +disabled interrupts. gfp flags passed to increase_address_space() may allow +sleeping, so it comes to this: + + BUG: sleeping function called from invalid context at mm/page_alloc.c:4342 + in_atomic(): 1, irqs_disabled(): 1, pid: 21555, name: epdcbbf1qnhbsd8 + + Call Trace: + dump_stack+0x66/0x8b + ___might_sleep+0xec/0x110 + __alloc_pages_nodemask+0x104/0x300 + get_zeroed_page+0x15/0x40 + iommu_map_page+0xdd/0x3e0 + amd_iommu_map+0x50/0x70 + iommu_map+0x106/0x220 + vfio_iommu_type1_ioctl+0x76e/0x950 [vfio_iommu_type1] + do_vfs_ioctl+0xa3/0x6f0 + ksys_ioctl+0x66/0x70 + __x64_sys_ioctl+0x16/0x20 + do_syscall_64+0x4e/0x100 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fix this by moving get_zeroed_page() out of spin_lock/unlock section. + +Fixes: 754265bcab ("iommu/amd: Fix race in increase_address_space()") +Signed-off-by: Andrey Ryabinin +Acked-by: Will Deacon +Cc: +Link: https://lore.kernel.org/r/20210217143004.19165-1-arbn@yandex-team.com +Signed-off-by: Joerg Roedel +Signed-off-by: Andrey Ryabinin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd/iommu.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/iommu/amd/iommu.c ++++ b/drivers/iommu/amd/iommu.c +@@ -1502,6 +1502,10 @@ static bool increase_address_space(struc + bool ret = true; + u64 *pte; + ++ pte = (void *)get_zeroed_page(gfp); ++ if (!pte) ++ return false; ++ + spin_lock_irqsave(&domain->lock, flags); + + amd_iommu_domain_get_pgtable(domain, &pgtable); +@@ -1513,10 +1517,6 @@ static bool increase_address_space(struc + if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) + goto out; + +- pte = (void *)get_zeroed_page(gfp); +- if (!pte) +- goto out; +- + *pte = PM_LEVEL_PDE(pgtable.mode, iommu_virt_to_phys(pgtable.root)); + + pgtable.root = pte; +@@ -1530,10 +1530,12 @@ static bool increase_address_space(struc + */ + amd_iommu_domain_set_pgtable(domain, pte, pgtable.mode); + ++ pte = NULL; + ret = true; + + out: + spin_unlock_irqrestore(&domain->lock, flags); ++ free_page((unsigned long)pte); + + return ret; + } diff --git a/queue-5.11/media-cedrus-remove-checking-for-required-controls.patch b/queue-5.11/media-cedrus-remove-checking-for-required-controls.patch new file mode 100644 index 00000000000..c9f55253d4c --- /dev/null +++ b/queue-5.11/media-cedrus-remove-checking-for-required-controls.patch @@ -0,0 +1,214 @@ +From 7072db89572135f28cad65f15877bf7e67cf2ff8 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Wed, 23 Dec 2020 12:06:58 +0100 +Subject: media: cedrus: Remove checking for required controls + +From: Jernej Skrabec + +commit 7072db89572135f28cad65f15877bf7e67cf2ff8 upstream. + +According to v4l2 request api specifications, it's allowed to skip +control if its content isn't changed for performance reasons. Cedrus +driver predates that, so it has implemented mechanism to check if all +required controls are included in one request. + +Conform to specifications with removing that mechanism. + +Note that this mechanism with static required flag isn't very good +anyway because need for control is usually signaled in other controls. + +Fixes: 50e761516f2b ("media: platform: Add Cedrus VPU decoder driver") +Signed-off-by: Jernej Skrabec +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/sunxi/cedrus/cedrus.c | 49 ---------------------------- + drivers/staging/media/sunxi/cedrus/cedrus.h | 1 + 2 files changed, 50 deletions(-) + +--- a/drivers/staging/media/sunxi/cedrus/cedrus.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c +@@ -34,56 +34,48 @@ static const struct cedrus_control cedru + .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, + }, + .codec = CEDRUS_CODEC_MPEG2, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, + }, + .codec = CEDRUS_CODEC_MPEG2, +- .required = false, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_H264_DECODE_PARAMS, + }, + .codec = CEDRUS_CODEC_H264, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_H264_SLICE_PARAMS, + }, + .codec = CEDRUS_CODEC_H264, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_H264_SPS, + }, + .codec = CEDRUS_CODEC_H264, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_H264_PPS, + }, + .codec = CEDRUS_CODEC_H264, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_H264_SCALING_MATRIX, + }, + .codec = CEDRUS_CODEC_H264, +- .required = false, + }, + { + .cfg = { + .id = V4L2_CID_STATELESS_H264_PRED_WEIGHTS, + }, + .codec = CEDRUS_CODEC_H264, +- .required = false, + }, + { + .cfg = { +@@ -92,7 +84,6 @@ static const struct cedrus_control cedru + .def = V4L2_STATELESS_H264_DECODE_MODE_SLICE_BASED, + }, + .codec = CEDRUS_CODEC_H264, +- .required = false, + }, + { + .cfg = { +@@ -101,7 +92,6 @@ static const struct cedrus_control cedru + .def = V4L2_STATELESS_H264_START_CODE_NONE, + }, + .codec = CEDRUS_CODEC_H264, +- .required = false, + }, + /* + * We only expose supported profiles information, +@@ -120,28 +110,24 @@ static const struct cedrus_control cedru + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED), + }, + .codec = CEDRUS_CODEC_H264, +- .required = false, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, + }, + .codec = CEDRUS_CODEC_H265, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, + }, + .codec = CEDRUS_CODEC_H265, +- .required = true, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, + }, + .codec = CEDRUS_CODEC_H265, +- .required = true, + }, + { + .cfg = { +@@ -150,7 +136,6 @@ static const struct cedrus_control cedru + .def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED, + }, + .codec = CEDRUS_CODEC_H265, +- .required = false, + }, + { + .cfg = { +@@ -159,14 +144,12 @@ static const struct cedrus_control cedru + .def = V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE, + }, + .codec = CEDRUS_CODEC_H265, +- .required = false, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER, + }, + .codec = CEDRUS_CODEC_VP8, +- .required = true, + }, + }; + +@@ -227,12 +210,8 @@ static int cedrus_init_ctrls(struct cedr + static int cedrus_request_validate(struct media_request *req) + { + struct media_request_object *obj; +- struct v4l2_ctrl_handler *parent_hdl, *hdl; + struct cedrus_ctx *ctx = NULL; +- struct v4l2_ctrl *ctrl_test; + unsigned int count; +- unsigned int i; +- int ret = 0; + + list_for_each_entry(obj, &req->objects, list) { + struct vb2_buffer *vb; +@@ -259,34 +238,6 @@ static int cedrus_request_validate(struc + return -EINVAL; + } + +- parent_hdl = &ctx->hdl; +- +- hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl); +- if (!hdl) { +- v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control(s)\n"); +- return -ENOENT; +- } +- +- for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) { +- if (cedrus_controls[i].codec != ctx->current_codec || +- !cedrus_controls[i].required) +- continue; +- +- ctrl_test = v4l2_ctrl_request_hdl_ctrl_find(hdl, +- cedrus_controls[i].cfg.id); +- if (!ctrl_test) { +- v4l2_info(&ctx->dev->v4l2_dev, +- "Missing required codec control\n"); +- ret = -ENOENT; +- break; +- } +- } +- +- v4l2_ctrl_request_hdl_put(hdl); +- +- if (ret) +- return ret; +- + return vb2_request_validate(req); + } + +--- a/drivers/staging/media/sunxi/cedrus/cedrus.h ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.h +@@ -56,7 +56,6 @@ enum cedrus_h264_pic_type { + struct cedrus_control { + struct v4l2_ctrl_config cfg; + enum cedrus_codec codec; +- unsigned char required:1; + }; + + struct cedrus_h264_run { diff --git a/queue-5.11/nvme-pci-mark-kingston-skc2000-as-not-supporting-the-deepest-power-state.patch b/queue-5.11/nvme-pci-mark-kingston-skc2000-as-not-supporting-the-deepest-power-state.patch new file mode 100644 index 00000000000..cb994bbf1fa --- /dev/null +++ b/queue-5.11/nvme-pci-mark-kingston-skc2000-as-not-supporting-the-deepest-power-state.patch @@ -0,0 +1,40 @@ +From foo@baz Wed Mar 10 01:08:03 PM CET 2021 +From: "Zoltán Böszörményi" +Date: Sun, 21 Feb 2021 06:12:16 +0100 +Subject: nvme-pci: mark Kingston SKC2000 as not supporting the deepest power state + +From: "Zoltán Böszörményi" + +commit dc22c1c058b5c4fe967a20589e36f029ee42a706 upstream + +My 2TB SKC2000 showed the exact same symptoms that were provided +in 538e4a8c57 ("nvme-pci: avoid the deepest sleep state on +Kingston A2000 SSDs"), i.e. a complete NVME lockup that needed +cold boot to get it back. + +According to some sources, the A2000 is simply a rebadged +SKC2000 with a slightly optimized firmware. + +Adding the SKC2000 PCI ID to the quirk list with the same workaround +as the A2000 made my laptop survive a 5 hours long Yocto bootstrap +buildfest which reliably triggered the SSD lockup previously. + +Signed-off-by: Zoltán Böszörményi +Signed-off-by: Christoph Hellwig +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3261,6 +3261,8 @@ static const struct pci_device_id nvme_i + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, ++ { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ ++ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), diff --git a/queue-5.11/parisc-enable-mlong-calls-gcc-option-with-config_compile_test.patch b/queue-5.11/parisc-enable-mlong-calls-gcc-option-with-config_compile_test.patch new file mode 100644 index 00000000000..a9c96e5133b --- /dev/null +++ b/queue-5.11/parisc-enable-mlong-calls-gcc-option-with-config_compile_test.patch @@ -0,0 +1,52 @@ +From foo@baz Wed Mar 10 01:08:03 PM CET 2021 +From: Helge Deller +Date: Tue, 2 Mar 2021 21:07:07 +0100 +Subject: parisc: Enable -mlong-calls gcc option with CONFIG_COMPILE_TEST + +From: Helge Deller + +commit 778e45d7720d663811352943dd515b41f6849637 upstream + +The kernel test robot reported multiple linkage problems like this: + + hppa64-linux-ld: init/main.o(.init.text+0x56c): cannot reach printk + init/main.o: in function `unknown_bootoption': + (.init.text+0x56c): relocation truncated to fit: R_PARISC_PCREL22F against + symbol `printk' defined in .text.unlikely section in kernel/printk/printk.o + +There are two ways to solve it: +a) Enable the -mlong-call compiler option (CONFIG_MLONGCALLS), +b) Add long branch stub support in 64-bit linker. + +While b) is the long-term solution, this patch works around the issue by +automatically enabling the CONFIG_MLONGCALLS option when +CONFIG_COMPILE_TEST is set, which indicates that a non-production kernel +(e.g. 0-day kernel) is built. + +Signed-off-by: Helge Deller +Reported-by: kernel test robot +Fixes: 00e35f2b0e8a ("parisc: Enable -mlong-calls gcc option by default when !CONFIG_MODULES") +Cc: stable@vger.kernel.org # v5.6+ +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + arch/parisc/Kconfig | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -201,9 +201,12 @@ config PREFETCH + def_bool y + depends on PA8X00 || PA7200 + ++config PARISC_HUGE_KERNEL ++ def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST ++ + config MLONGCALLS +- def_bool y if !MODULES || UBSAN || FTRACE +- bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE ++ def_bool y if PARISC_HUGE_KERNEL ++ bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL + depends on PA8X00 + help + If you configure the kernel to include many drivers built-in instead diff --git a/queue-5.11/series b/queue-5.11/series index c73e97314fe..81d575b00f0 100644 --- a/queue-5.11/series +++ b/queue-5.11/series @@ -1 +1,17 @@ acpica-fix-race-in-generic_serial_bus-i2c-and-gpio-op_region-parameter-handling.patch +io_uring-fix-inconsistent-lock-state.patch +io_uring-deduplicate-core-cancellations-sequence.patch +io_uring-unpark-sqpoll-thread-for-cancelation.patch +io_uring-deduplicate-failing-task_work_add.patch +fs-provide-locked-helper-variant-of-close_fd_get_file.patch +io_uring-get-rid-of-intermediate-ioring_op_close-stage.patch +io_uring-io-wq-kill-off-now-unused-io_wq_work_no_cancel.patch +io_uring-io-wq-return-2-step-work-swap-scheme.patch +io_uring-don-t-take-uring_lock-during-iowq-cancel.patch +media-cedrus-remove-checking-for-required-controls.patch +nvme-pci-mark-kingston-skc2000-as-not-supporting-the-deepest-power-state.patch +parisc-enable-mlong-calls-gcc-option-with-config_compile_test.patch +arm64-make-cpu_big_endian-depend-on-ld.bfd-or-ld.lld-13.0.0.patch +btrfs-export-and-rename-qgroup_reserve_meta.patch +btrfs-don-t-flush-from-btrfs_delayed_inode_reserve_metadata.patch +iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch