From: Greg Kroah-Hartman Date: Tue, 18 Oct 2022 18:14:45 +0000 (+0200) Subject: drop some btrfs lockdep patches X-Git-Tag: v6.0.3~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b450c35b4bb6e14a7c124e97979c22242ee54ad;p=thirdparty%2Fkernel%2Fstable-queue.git drop some btrfs lockdep patches --- diff --git a/queue-5.15/btrfs-add-macros-for-annotating-wait-events-with-loc.patch b/queue-5.15/btrfs-add-macros-for-annotating-wait-events-with-loc.patch deleted file mode 100644 index 506c28dd9ec..00000000000 --- a/queue-5.15/btrfs-add-macros-for-annotating-wait-events-with-loc.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 1587253bfd3c2e90d8659abd8093396881f622fc Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:46 -0700 -Subject: btrfs: add macros for annotating wait events with lockdep - -From: Ioannis Angelakopoulos - -[ Upstream commit ab9a323f9ab576000795285dd7ac6afeedf29e32 ] - -Introduce four macros that are used to annotate wait events in btrfs code -with lockdep; - - 1) the btrfs_lockdep_init_map - 2) the btrfs_lockdep_acquire, - 3) the btrfs_lockdep_release - 4) the btrfs_might_wait_for_event macros. - -The btrfs_lockdep_init_map macro is used to initialize a lockdep map. - -The btrfs_lockdep_ macros are used by threads to take -the lockdep map as readers (shared lock) and release it, respectively. - -The btrfs_might_wait_for_event macro is used by threads to take the -lockdep map as writers (exclusive lock) and release it. - -In general, the lockdep annotation for wait events work as follows: - -The condition for a wait event can be modified and signaled at the same -time by multiple threads. These threads hold the lockdep map as readers -when they enter a context in which blocking would prevent signaling the -condition. Frequently, this occurs when a thread violates a condition -(lockdep map acquire), before restoring it and signaling it at a later -point (lockdep map release). - -The threads that block on the wait event take the lockdep map as writers -(exclusive lock). These threads have to block until all the threads that -hold the lockdep map as readers signal the condition for the wait event -and release the lockdep map. - -The lockdep annotation is used to warn about potential deadlock scenarios -that involve the threads that modify and signal the wait event condition -and threads that block on the wait event. A simple example is illustrated -below: - -Without lockdep: - -TA TB -cond = false - lock(A) - wait_event(w, cond) - unlock(A) -lock(A) -cond = true -signal(w) -unlock(A) - -With lockdep: - -TA TB -rwsem_acquire_read(lockdep_map) -cond = false - lock(A) - rwsem_acquire(lockdep_map) - rwsem_release(lockdep_map) - wait_event(w, cond) - unlock(A) -lock(A) -cond = true -signal(w) -unlock(A) -rwsem_release(lockdep_map) - -In the second case, with the lockdep annotation, lockdep would warn about -an ABBA deadlock, while the first case would just deadlock at some point. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 02d3ee6c7d9b..3ab1219db32e 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1108,6 +1108,51 @@ enum { - BTRFS_ROOT_RESET_LOCKDEP_CLASS, - }; - -+/* -+ * Lockdep annotation for wait events. -+ * -+ * @owner: The struct where the lockdep map is defined -+ * @lock: The lockdep map corresponding to a wait event -+ * -+ * This macro is used to annotate a wait event. In this case a thread acquires -+ * the lockdep map as writer (exclusive lock) because it has to block until all -+ * the threads that hold the lock as readers signal the condition for the wait -+ * event and release their locks. -+ */ -+#define btrfs_might_wait_for_event(owner, lock) \ -+ do { \ -+ rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_); \ -+ rwsem_release(&owner->lock##_map, _THIS_IP_); \ -+ } while (0) -+ -+/* -+ * Protection for the resource/condition of a wait event. -+ * -+ * @owner: The struct where the lockdep map is defined -+ * @lock: The lockdep map corresponding to a wait event -+ * -+ * Many threads can modify the condition for the wait event at the same time -+ * and signal the threads that block on the wait event. The threads that modify -+ * the condition and do the signaling acquire the lock as readers (shared -+ * lock). -+ */ -+#define btrfs_lockdep_acquire(owner, lock) \ -+ rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_) -+ -+/* -+ * Used after signaling the condition for a wait event to release the lockdep -+ * map held by a reader thread. -+ */ -+#define btrfs_lockdep_release(owner, lock) \ -+ rwsem_release(&owner->lock##_map, _THIS_IP_) -+ -+/* Initialization of the lockdep map */ -+#define btrfs_lockdep_init_map(owner, lock) \ -+ do { \ -+ static struct lock_class_key lock##_key; \ -+ lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \ -+ } while (0) -+ - static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info) - { - clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags); --- -2.35.1 - diff --git a/queue-5.15/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch b/queue-5.15/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch deleted file mode 100644 index 7c2e9f44940..00000000000 --- a/queue-5.15/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 28946141bf21e5e533d472b762e7a4dac31be136 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:57 -0700 -Subject: btrfs: change the lockdep class of free space inode's invalidate_lock - -From: Ioannis Angelakopoulos - -[ Upstream commit 9d7464c87b159bbf763c24faeb7a2dcaac96e4a1 ] - -Reinitialize the class of the lockdep map for struct inode's -mapping->invalidate_lock in load_free_space_cache() function in -fs/btrfs/free-space-cache.c. This will prevent lockdep from producing -false positives related to execution paths that make use of free space -inodes and paths that make use of normal inodes. - -Specifically, with this change lockdep will create separate lock -dependencies that include the invalidate_lock, in the case that free -space inodes are used and in the case that normal inodes are used. - -The lockdep class for this lock was first initialized in -inode_init_always() in fs/inode.c. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/free-space-cache.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index 529907ea3825..456da08feccd 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -899,6 +899,8 @@ static int copy_free_space_cache(struct btrfs_block_group *block_group, - return ret; - } - -+static struct lock_class_key btrfs_free_space_inode_key; -+ - int load_free_space_cache(struct btrfs_block_group *block_group) - { - struct btrfs_fs_info *fs_info = block_group->fs_info; -@@ -968,6 +970,14 @@ int load_free_space_cache(struct btrfs_block_group *block_group) - } - spin_unlock(&block_group->lock); - -+ /* -+ * Reinitialize the class of struct inode's mapping->invalidate_lock for -+ * free space inodes to prevent false positives related to locks for normal -+ * inodes. -+ */ -+ lockdep_set_class(&(&inode->i_data)->invalidate_lock, -+ &btrfs_free_space_inode_key); -+ - ret = __load_free_space_cache(fs_info->tree_root, inode, &tmp_ctl, - path, block_group->start); - btrfs_free_path(path); --- -2.35.1 - diff --git a/queue-5.15/series b/queue-5.15/series index adeb02eb715..2a2cfe490c2 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -535,8 +535,6 @@ kselftest-arm64-fix-validatation-termination-record-.patch arm64-dts-imx8mq-librem5-add-bq25895-as-max17055-s-p.patch arm-orion-fix-include-path.patch btrfs-dump-extra-info-if-one-free-space-cache-has-mo.patch -btrfs-add-macros-for-annotating-wait-events-with-loc.patch -btrfs-change-the-lockdep-class-of-free-space-inode-s.patch btrfs-scrub-try-to-fix-super-block-errors.patch btrfs-don-t-print-information-about-space-cache-or-t.patch arm64-dts-uniphier-add-usb-device-support-for-pxs3-r.patch diff --git a/queue-5.19/btrfs-add-macros-for-annotating-wait-events-with-loc.patch b/queue-5.19/btrfs-add-macros-for-annotating-wait-events-with-loc.patch deleted file mode 100644 index ddb4b4aad91..00000000000 --- a/queue-5.19/btrfs-add-macros-for-annotating-wait-events-with-loc.patch +++ /dev/null @@ -1,143 +0,0 @@ -From e444bea4707bcdad792b420041dfd32f9201d1d6 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:46 -0700 -Subject: btrfs: add macros for annotating wait events with lockdep - -From: Ioannis Angelakopoulos - -[ Upstream commit ab9a323f9ab576000795285dd7ac6afeedf29e32 ] - -Introduce four macros that are used to annotate wait events in btrfs code -with lockdep; - - 1) the btrfs_lockdep_init_map - 2) the btrfs_lockdep_acquire, - 3) the btrfs_lockdep_release - 4) the btrfs_might_wait_for_event macros. - -The btrfs_lockdep_init_map macro is used to initialize a lockdep map. - -The btrfs_lockdep_ macros are used by threads to take -the lockdep map as readers (shared lock) and release it, respectively. - -The btrfs_might_wait_for_event macro is used by threads to take the -lockdep map as writers (exclusive lock) and release it. - -In general, the lockdep annotation for wait events work as follows: - -The condition for a wait event can be modified and signaled at the same -time by multiple threads. These threads hold the lockdep map as readers -when they enter a context in which blocking would prevent signaling the -condition. Frequently, this occurs when a thread violates a condition -(lockdep map acquire), before restoring it and signaling it at a later -point (lockdep map release). - -The threads that block on the wait event take the lockdep map as writers -(exclusive lock). These threads have to block until all the threads that -hold the lockdep map as readers signal the condition for the wait event -and release the lockdep map. - -The lockdep annotation is used to warn about potential deadlock scenarios -that involve the threads that modify and signal the wait event condition -and threads that block on the wait event. A simple example is illustrated -below: - -Without lockdep: - -TA TB -cond = false - lock(A) - wait_event(w, cond) - unlock(A) -lock(A) -cond = true -signal(w) -unlock(A) - -With lockdep: - -TA TB -rwsem_acquire_read(lockdep_map) -cond = false - lock(A) - rwsem_acquire(lockdep_map) - rwsem_release(lockdep_map) - wait_event(w, cond) - unlock(A) -lock(A) -cond = true -signal(w) -unlock(A) -rwsem_release(lockdep_map) - -In the second case, with the lockdep annotation, lockdep would warn about -an ABBA deadlock, while the first case would just deadlock at some point. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 1bbc810574f2..8d35db5b2b62 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1148,6 +1148,51 @@ enum { - BTRFS_ROOT_RESET_LOCKDEP_CLASS, - }; - -+/* -+ * Lockdep annotation for wait events. -+ * -+ * @owner: The struct where the lockdep map is defined -+ * @lock: The lockdep map corresponding to a wait event -+ * -+ * This macro is used to annotate a wait event. In this case a thread acquires -+ * the lockdep map as writer (exclusive lock) because it has to block until all -+ * the threads that hold the lock as readers signal the condition for the wait -+ * event and release their locks. -+ */ -+#define btrfs_might_wait_for_event(owner, lock) \ -+ do { \ -+ rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_); \ -+ rwsem_release(&owner->lock##_map, _THIS_IP_); \ -+ } while (0) -+ -+/* -+ * Protection for the resource/condition of a wait event. -+ * -+ * @owner: The struct where the lockdep map is defined -+ * @lock: The lockdep map corresponding to a wait event -+ * -+ * Many threads can modify the condition for the wait event at the same time -+ * and signal the threads that block on the wait event. The threads that modify -+ * the condition and do the signaling acquire the lock as readers (shared -+ * lock). -+ */ -+#define btrfs_lockdep_acquire(owner, lock) \ -+ rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_) -+ -+/* -+ * Used after signaling the condition for a wait event to release the lockdep -+ * map held by a reader thread. -+ */ -+#define btrfs_lockdep_release(owner, lock) \ -+ rwsem_release(&owner->lock##_map, _THIS_IP_) -+ -+/* Initialization of the lockdep map */ -+#define btrfs_lockdep_init_map(owner, lock) \ -+ do { \ -+ static struct lock_class_key lock##_key; \ -+ lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \ -+ } while (0) -+ - static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info) - { - clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags); --- -2.35.1 - diff --git a/queue-5.19/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch b/queue-5.19/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch index 34a4760e637..c6447df37cc 100644 --- a/queue-5.19/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch +++ b/queue-5.19/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch @@ -62,14 +62,12 @@ Signed-off-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- - fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++-------------- + fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index d9577f822ba5..19e58e553fa1 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c -@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, +@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btr struct btrfs_free_space *info, u64 offset, u64 bytes, bool update_stats); @@ -95,7 +93,7 @@ index d9577f822ba5..19e58e553fa1 100644 static struct inode *__lookup_free_space_inode(struct btrfs_root *root, struct btrfs_path *path, u64 offset) -@@ -881,7 +900,14 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, +@@ -881,7 +900,14 @@ out: return ret; free_cache: io_ctl_drop_pages(&io_ctl); @@ -111,7 +109,7 @@ index d9577f822ba5..19e58e553fa1 100644 goto out; } -@@ -1017,7 +1043,13 @@ int load_free_space_cache(struct btrfs_block_group *block_group) +@@ -1007,7 +1033,13 @@ int load_free_space_cache(struct btrfs_b if (ret == 0) ret = 1; } else { @@ -125,7 +123,7 @@ index d9577f822ba5..19e58e553fa1 100644 btrfs_warn(fs_info, "block group %llu has wrong amount of free space", block_group->start); -@@ -2980,25 +3012,6 @@ static void __btrfs_return_cluster_to_free_space( +@@ -2970,25 +3002,6 @@ static void __btrfs_return_cluster_to_fr btrfs_put_block_group(block_group); } @@ -151,6 +149,3 @@ index d9577f822ba5..19e58e553fa1 100644 void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl) { spin_lock(&ctl->tree_lock); --- -2.35.1 - diff --git a/queue-5.19/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch b/queue-5.19/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch deleted file mode 100644 index 532af7cc027..00000000000 --- a/queue-5.19/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 64796875b3d6eef72b90481ed83ae4db55ce12c8 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:57 -0700 -Subject: btrfs: change the lockdep class of free space inode's invalidate_lock - -From: Ioannis Angelakopoulos - -[ Upstream commit 9d7464c87b159bbf763c24faeb7a2dcaac96e4a1 ] - -Reinitialize the class of the lockdep map for struct inode's -mapping->invalidate_lock in load_free_space_cache() function in -fs/btrfs/free-space-cache.c. This will prevent lockdep from producing -false positives related to execution paths that make use of free space -inodes and paths that make use of normal inodes. - -Specifically, with this change lockdep will create separate lock -dependencies that include the invalidate_lock, in the case that free -space inodes are used and in the case that normal inodes are used. - -The lockdep class for this lock was first initialized in -inode_init_always() in fs/inode.c. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/free-space-cache.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index 16710d4571da..d9577f822ba5 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -920,6 +920,8 @@ static int copy_free_space_cache(struct btrfs_block_group *block_group, - return ret; - } - -+static struct lock_class_key btrfs_free_space_inode_key; -+ - int load_free_space_cache(struct btrfs_block_group *block_group) - { - struct btrfs_fs_info *fs_info = block_group->fs_info; -@@ -989,6 +991,14 @@ int load_free_space_cache(struct btrfs_block_group *block_group) - } - spin_unlock(&block_group->lock); - -+ /* -+ * Reinitialize the class of struct inode's mapping->invalidate_lock for -+ * free space inodes to prevent false positives related to locks for normal -+ * inodes. -+ */ -+ lockdep_set_class(&(&inode->i_data)->invalidate_lock, -+ &btrfs_free_space_inode_key); -+ - ret = __load_free_space_cache(fs_info->tree_root, inode, &tmp_ctl, - path, block_group->start); - btrfs_free_path(path); --- -2.35.1 - diff --git a/queue-5.19/series b/queue-5.19/series index b35ef7fad9b..3cab85a782f 100644 --- a/queue-5.19/series +++ b/queue-5.19/series @@ -724,8 +724,6 @@ arm64-dts-imx8mm-kontron-use-the-vselect-signal-to-s.patch arm64-dts-imx8mq-librem5-add-bq25895-as-max17055-s-p.patch arm-orion-fix-include-path.patch btrfs-dump-extra-info-if-one-free-space-cache-has-mo.patch -btrfs-add-macros-for-annotating-wait-events-with-loc.patch -btrfs-change-the-lockdep-class-of-free-space-inode-s.patch btrfs-scrub-properly-report-super-block-errors-in-sy.patch btrfs-scrub-try-to-fix-super-block-errors.patch btrfs-don-t-print-information-about-space-cache-or-t.patch diff --git a/queue-6.0/btrfs-add-lockdep-annotations-for-num_extwriters-wai.patch b/queue-6.0/btrfs-add-lockdep-annotations-for-num_extwriters-wai.patch deleted file mode 100644 index 971eb95c278..00000000000 --- a/queue-6.0/btrfs-add-lockdep-annotations-for-num_extwriters-wai.patch +++ /dev/null @@ -1,114 +0,0 @@ -From cfca5f04b3bb29b3a74ff00154aacebe440602ed Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:50 -0700 -Subject: btrfs: add lockdep annotations for num_extwriters wait event - -From: Ioannis Angelakopoulos - -[ Upstream commit 5a9ba6709f13313984900d635b4c73c9eb7d644e ] - -Similarly to the num_writers wait event in fs/btrfs/transaction.c add a -lockdep annotation for the num_extwriters wait event. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 1 + - fs/btrfs/disk-io.c | 1 + - fs/btrfs/transaction.c | 13 +++++++++++++ - 3 files changed, 15 insertions(+) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 707e644bab92..e886cf639c0f 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1097,6 +1097,7 @@ struct btrfs_fs_info { - * compiled without lockdep). - */ - struct lockdep_map btrfs_trans_num_writers_map; -+ struct lockdep_map btrfs_trans_num_extwriters_map; - - #ifdef CONFIG_BTRFS_FS_REF_VERIFY - spinlock_t ref_verify_lock; -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index a04b32f7df9d..811d743e26e6 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -2991,6 +2991,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) - seqlock_init(&fs_info->profiles_lock); - - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers); -+ btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters); - - INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); - INIT_LIST_HEAD(&fs_info->space_info); -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index b3cb54d852f8..44e47db4c8e8 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -314,6 +314,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, - extwriter_counter_inc(cur_trans, type); - spin_unlock(&fs_info->trans_lock); - btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers); -+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_extwriters); - return 0; - } - spin_unlock(&fs_info->trans_lock); -@@ -336,6 +337,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, - return -ENOMEM; - - btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers); -+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_extwriters); - - spin_lock(&fs_info->trans_lock); - if (fs_info->running_transaction) { -@@ -343,11 +345,13 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, - * someone started a transaction after we unlocked. Make sure - * to redo the checks above - */ -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters); - btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - kfree(cur_trans); - goto loop; - } else if (BTRFS_FS_ERROR(fs_info)) { - spin_unlock(&fs_info->trans_lock); -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters); - btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - kfree(cur_trans); - return -EROFS; -@@ -1028,6 +1032,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, - - cond_wake_up(&cur_trans->writer_wait); - -+ btrfs_lockdep_release(info, btrfs_trans_num_extwriters); - btrfs_lockdep_release(info, btrfs_trans_num_writers); - - btrfs_put_transaction(cur_trans); -@@ -2270,6 +2275,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - if (ret) - goto lockdep_release; - -+ /* -+ * The thread has started/joined the transaction thus it holds the -+ * lockdep map as a reader. It has to release it before acquiring the -+ * lockdep map as a writer. -+ */ -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters); -+ btrfs_might_wait_for_event(fs_info, btrfs_trans_num_extwriters); - wait_event(cur_trans->writer_wait, - extwriter_counter_read(cur_trans) == 0); - -@@ -2541,6 +2553,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - return ret; - - lockdep_release: -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters); - btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - goto cleanup_transaction; - } --- -2.35.1 - diff --git a/queue-6.0/btrfs-add-lockdep-annotations-for-num_writers-wait-e.patch b/queue-6.0/btrfs-add-lockdep-annotations-for-num_writers-wait-e.patch deleted file mode 100644 index 9d00df13d20..00000000000 --- a/queue-6.0/btrfs-add-lockdep-annotations-for-num_writers-wait-e.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 4c3eac5e35f1d4118988475c65fddc92b7dced27 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:48 -0700 -Subject: btrfs: add lockdep annotations for num_writers wait event - -From: Ioannis Angelakopoulos - -[ Upstream commit e1489b4fe6045a79a5e9c658eed65311977e230a ] - -Annotate the num_writers wait event in fs/btrfs/transaction.c with -lockdep in order to catch deadlocks involving this wait event. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 6 ++++++ - fs/btrfs/disk-io.c | 2 ++ - fs/btrfs/transaction.c | 38 +++++++++++++++++++++++++++++++++----- - 3 files changed, 41 insertions(+), 5 deletions(-) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index dfeb7174219e..707e644bab92 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1092,6 +1092,12 @@ struct btrfs_fs_info { - /* Updates are not protected by any lock */ - struct btrfs_commit_stats commit_stats; - -+ /* -+ * Annotations for transaction events (structures are empty when -+ * compiled without lockdep). -+ */ -+ struct lockdep_map btrfs_trans_num_writers_map; -+ - #ifdef CONFIG_BTRFS_FS_REF_VERIFY - spinlock_t ref_verify_lock; - struct rb_root block_tree; -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 2633137c3e9f..a04b32f7df9d 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -2990,6 +2990,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) - mutex_init(&fs_info->zoned_data_reloc_io_lock); - seqlock_init(&fs_info->profiles_lock); - -+ btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers); -+ - INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); - INIT_LIST_HEAD(&fs_info->space_info); - INIT_LIST_HEAD(&fs_info->tree_mod_seq_list); -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index 0bec10740ad3..b3cb54d852f8 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -313,6 +313,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, - atomic_inc(&cur_trans->num_writers); - extwriter_counter_inc(cur_trans, type); - spin_unlock(&fs_info->trans_lock); -+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers); - return 0; - } - spin_unlock(&fs_info->trans_lock); -@@ -334,16 +335,20 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, - if (!cur_trans) - return -ENOMEM; - -+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers); -+ - spin_lock(&fs_info->trans_lock); - if (fs_info->running_transaction) { - /* - * someone started a transaction after we unlocked. Make sure - * to redo the checks above - */ -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - kfree(cur_trans); - goto loop; - } else if (BTRFS_FS_ERROR(fs_info)) { - spin_unlock(&fs_info->trans_lock); -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - kfree(cur_trans); - return -EROFS; - } -@@ -1022,6 +1027,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, - extwriter_counter_dec(cur_trans, trans->type); - - cond_wake_up(&cur_trans->writer_wait); -+ -+ btrfs_lockdep_release(info, btrfs_trans_num_writers); -+ - btrfs_put_transaction(cur_trans); - - if (current->journal_info == trans) -@@ -1994,6 +2002,12 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, int err) - if (cur_trans == fs_info->running_transaction) { - cur_trans->state = TRANS_STATE_COMMIT_DOING; - spin_unlock(&fs_info->trans_lock); -+ -+ /* -+ * The thread has already released the lockdep map as reader -+ * already in btrfs_commit_transaction(). -+ */ -+ btrfs_might_wait_for_event(fs_info, btrfs_trans_num_writers); - wait_event(cur_trans->writer_wait, - atomic_read(&cur_trans->num_writers) == 1); - -@@ -2222,7 +2236,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - btrfs_put_transaction(prev_trans); - if (ret) -- goto cleanup_transaction; -+ goto lockdep_release; - } else { - spin_unlock(&fs_info->trans_lock); - } -@@ -2236,7 +2250,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - */ - if (BTRFS_FS_ERROR(fs_info)) { - ret = -EROFS; -- goto cleanup_transaction; -+ goto lockdep_release; - } - } - -@@ -2250,19 +2264,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - ret = btrfs_start_delalloc_flush(fs_info); - if (ret) -- goto cleanup_transaction; -+ goto lockdep_release; - - ret = btrfs_run_delayed_items(trans); - if (ret) -- goto cleanup_transaction; -+ goto lockdep_release; - - wait_event(cur_trans->writer_wait, - extwriter_counter_read(cur_trans) == 0); - - /* some pending stuffs might be added after the previous flush. */ - ret = btrfs_run_delayed_items(trans); -- if (ret) -+ if (ret) { -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - goto cleanup_transaction; -+ } - - btrfs_wait_delalloc_flush(fs_info); - -@@ -2284,6 +2300,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - add_pending_snapshot(trans); - cur_trans->state = TRANS_STATE_COMMIT_DOING; - spin_unlock(&fs_info->trans_lock); -+ -+ /* -+ * The thread has started/joined the transaction thus it holds the -+ * lockdep map as a reader. It has to release it before acquiring the -+ * lockdep map as a writer. -+ */ -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); -+ btrfs_might_wait_for_event(fs_info, btrfs_trans_num_writers); - wait_event(cur_trans->writer_wait, - atomic_read(&cur_trans->num_writers) == 1); - -@@ -2515,6 +2539,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - cleanup_transaction(trans, ret); - - return ret; -+ -+lockdep_release: -+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); -+ goto cleanup_transaction; - } - - /* --- -2.35.1 - diff --git a/queue-6.0/btrfs-add-lockdep-annotations-for-pending_ordered-wa.patch b/queue-6.0/btrfs-add-lockdep-annotations-for-pending_ordered-wa.patch deleted file mode 100644 index 336e764ee3d..00000000000 --- a/queue-6.0/btrfs-add-lockdep-annotations-for-pending_ordered-wa.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 5898b5a0ae847ba581045a1ebfa11348731daa5d Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:54 -0700 -Subject: btrfs: add lockdep annotations for pending_ordered wait event - -From: Ioannis Angelakopoulos - -[ Upstream commit 8b53779eaa98b55f4cccadd4d12b3233e9633140 ] - -In contrast to the num_writers and num_extwriters wait events, the -condition for the pending ordered wait event is signaled in a different -context from the wait event itself. The condition signaling occurs in -btrfs_remove_ordered_extent() in fs/btrfs/ordered-data.c while the wait -event is implemented in btrfs_commit_transaction() in -fs/btrfs/transaction.c - -Thus the thread signaling the condition has to acquire the lockdep map -as a reader at the start of btrfs_remove_ordered_extent() and release it -after it has signaled the condition. In this case some dependencies -might be left out due to the placement of the annotation, but it is -better than no annotation at all. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 1 + - fs/btrfs/disk-io.c | 1 + - fs/btrfs/ordered-data.c | 3 +++ - fs/btrfs/transaction.c | 1 + - 4 files changed, 6 insertions(+) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index f8172e269f03..8bd9a6d5ade6 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1099,6 +1099,7 @@ struct btrfs_fs_info { - struct lockdep_map btrfs_trans_num_writers_map; - struct lockdep_map btrfs_trans_num_extwriters_map; - struct lockdep_map btrfs_state_change_map[4]; -+ struct lockdep_map btrfs_trans_pending_ordered_map; - - #ifdef CONFIG_BTRFS_FS_REF_VERIFY - spinlock_t ref_verify_lock; -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 68c6cb4e9283..393553fdfed6 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -2992,6 +2992,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) - - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers); - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters); -+ btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered); - btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start, - BTRFS_LOCKDEP_TRANS_COMMIT_START); - btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked, -diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c -index 1952ac85222c..2a4cb6db42d1 100644 ---- a/fs/btrfs/ordered-data.c -+++ b/fs/btrfs/ordered-data.c -@@ -525,6 +525,7 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, - struct rb_node *node; - bool pending; - -+ btrfs_lockdep_acquire(fs_info, btrfs_trans_pending_ordered); - /* This is paired with btrfs_add_ordered_extent. */ - spin_lock(&btrfs_inode->lock); - btrfs_mod_outstanding_extents(btrfs_inode, -1); -@@ -580,6 +581,8 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, - } - } - -+ btrfs_lockdep_release(fs_info, btrfs_trans_pending_ordered); -+ - spin_lock(&root->ordered_extent_lock); - list_del_init(&entry->root_extent_list); - root->nr_ordered_extents--; -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index d3576f84020d..6e3b2cb6a04a 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -2310,6 +2310,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - * transaction. Otherwise if this transaction commits before the ordered - * extents complete we lose logged data after a power failure. - */ -+ btrfs_might_wait_for_event(fs_info, btrfs_trans_pending_ordered); - wait_event(cur_trans->pending_wait, - atomic_read(&cur_trans->pending_ordered) == 0); - --- -2.35.1 - diff --git a/queue-6.0/btrfs-add-lockdep-annotations-for-the-ordered-extent.patch b/queue-6.0/btrfs-add-lockdep-annotations-for-the-ordered-extent.patch deleted file mode 100644 index 1fc9d111f63..00000000000 --- a/queue-6.0/btrfs-add-lockdep-annotations-for-the-ordered-extent.patch +++ /dev/null @@ -1,158 +0,0 @@ -From dbaab36298dc01beea6a2d8ffe12e7d7180f2b30 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:59 -0700 -Subject: btrfs: add lockdep annotations for the ordered extents wait event - -From: Ioannis Angelakopoulos - -[ Upstream commit 5f4403e10f9b75b081bcc763b98d73e29de8c248 ] - -This wait event is very similar to the pending ordered wait event in the -sense that it occurs in a different context than the condition signaling -for the event. The signaling occurs in btrfs_remove_ordered_extent() -while the wait event is implemented in btrfs_start_ordered_extent() in -fs/btrfs/ordered-data.c - -However, in this case a thread must not acquire the lockdep map for the -ordered extents wait event when the ordered extent is related to a free -space inode. That is because lockdep creates dependencies between locks -acquired both in execution paths related to normal inodes and paths -related to free space inodes, thus leading to false positives. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 1 + - fs/btrfs/disk-io.c | 1 + - fs/btrfs/inode.c | 13 +++++++++++++ - fs/btrfs/ordered-data.c | 18 ++++++++++++++++++ - 4 files changed, 33 insertions(+) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 8bd9a6d5ade6..804962f97452 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1100,6 +1100,7 @@ struct btrfs_fs_info { - struct lockdep_map btrfs_trans_num_extwriters_map; - struct lockdep_map btrfs_state_change_map[4]; - struct lockdep_map btrfs_trans_pending_ordered_map; -+ struct lockdep_map btrfs_ordered_extent_map; - - #ifdef CONFIG_BTRFS_FS_REF_VERIFY - spinlock_t ref_verify_lock; -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 393553fdfed6..e0e1730e67d7 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -2993,6 +2993,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers); - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters); - btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered); -+ btrfs_lockdep_init_map(fs_info, btrfs_ordered_extent); - btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start, - BTRFS_LOCKDEP_TRANS_COMMIT_START); - btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked, -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 1372210869b1..b06955727055 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -3225,6 +3225,8 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) - clear_bits |= EXTENT_DELALLOC_NEW; - - freespace_inode = btrfs_is_free_space_inode(inode); -+ if (!freespace_inode) -+ btrfs_lockdep_acquire(fs_info, btrfs_ordered_extent); - - if (test_bit(BTRFS_ORDERED_IOERR, &ordered_extent->flags)) { - ret = -EIO; -@@ -8959,6 +8961,7 @@ void btrfs_destroy_inode(struct inode *vfs_inode) - struct btrfs_ordered_extent *ordered; - struct btrfs_inode *inode = BTRFS_I(vfs_inode); - struct btrfs_root *root = inode->root; -+ bool freespace_inode; - - WARN_ON(!hlist_empty(&vfs_inode->i_dentry)); - WARN_ON(vfs_inode->i_data.nrpages); -@@ -8980,6 +8983,12 @@ void btrfs_destroy_inode(struct inode *vfs_inode) - if (!root) - return; - -+ /* -+ * If this is a free space inode do not take the ordered extents lockdep -+ * map. -+ */ -+ freespace_inode = btrfs_is_free_space_inode(inode); -+ - while (1) { - ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1); - if (!ordered) -@@ -8988,6 +8997,10 @@ void btrfs_destroy_inode(struct inode *vfs_inode) - btrfs_err(root->fs_info, - "found ordered extent %llu %llu on inode cleanup", - ordered->file_offset, ordered->num_bytes); -+ -+ if (!freespace_inode) -+ btrfs_lockdep_acquire(root->fs_info, btrfs_ordered_extent); -+ - btrfs_remove_ordered_extent(inode, ordered); - btrfs_put_ordered_extent(ordered); - btrfs_put_ordered_extent(ordered); -diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c -index 2a4cb6db42d1..eb24a6d20ff8 100644 ---- a/fs/btrfs/ordered-data.c -+++ b/fs/btrfs/ordered-data.c -@@ -524,6 +524,13 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, - struct btrfs_fs_info *fs_info = root->fs_info; - struct rb_node *node; - bool pending; -+ bool freespace_inode; -+ -+ /* -+ * If this is a free space inode the thread has not acquired the ordered -+ * extents lockdep map. -+ */ -+ freespace_inode = btrfs_is_free_space_inode(btrfs_inode); - - btrfs_lockdep_acquire(fs_info, btrfs_trans_pending_ordered); - /* This is paired with btrfs_add_ordered_extent. */ -@@ -597,6 +604,8 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, - } - spin_unlock(&root->ordered_extent_lock); - wake_up(&entry->wait); -+ if (!freespace_inode) -+ btrfs_lockdep_release(fs_info, btrfs_ordered_extent); - } - - static void btrfs_run_ordered_extent_work(struct btrfs_work *work) -@@ -715,9 +724,16 @@ void btrfs_start_ordered_extent(struct btrfs_ordered_extent *entry, int wait) - u64 start = entry->file_offset; - u64 end = start + entry->num_bytes - 1; - struct btrfs_inode *inode = BTRFS_I(entry->inode); -+ bool freespace_inode; - - trace_btrfs_ordered_extent_start(inode, entry); - -+ /* -+ * If this is a free space inode do not take the ordered extents lockdep -+ * map. -+ */ -+ freespace_inode = btrfs_is_free_space_inode(inode); -+ - /* - * pages in the range can be dirty, clean or writeback. We - * start IO on any dirty ones so the wait doesn't stall waiting -@@ -726,6 +742,8 @@ void btrfs_start_ordered_extent(struct btrfs_ordered_extent *entry, int wait) - if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags)) - filemap_fdatawrite_range(inode->vfs_inode.i_mapping, start, end); - if (wait) { -+ if (!freespace_inode) -+ btrfs_might_wait_for_event(inode->root->fs_info, btrfs_ordered_extent); - wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE, - &entry->flags)); - } --- -2.35.1 - diff --git a/queue-6.0/btrfs-add-lockdep-annotations-for-transaction-states.patch b/queue-6.0/btrfs-add-lockdep-annotations-for-transaction-states.patch deleted file mode 100644 index 5fa5fefe581..00000000000 --- a/queue-6.0/btrfs-add-lockdep-annotations-for-transaction-states.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 3c196fc7745196ba3f6358ce334e0512366c86f6 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:52 -0700 -Subject: btrfs: add lockdep annotations for transaction states wait events - -From: Ioannis Angelakopoulos - -[ Upstream commit 3e738c531aad8caa7f3d20ab878a8a0d3574e730 ] - -Add lockdep annotations for the transaction states that have wait -events; - - 1) TRANS_STATE_COMMIT_START - 2) TRANS_STATE_UNBLOCKED - 3) TRANS_STATE_SUPER_COMMITTED - 4) TRANS_STATE_COMPLETED - -The new macros introduced here to annotate the transaction states wait -events have the same effect as the generic lockdep annotation macros. - -With the exception of the lockdep annotation for TRANS_STATE_COMMIT_START -the transaction thread has to acquire the lockdep maps for the -transaction states as reader after the lockdep map for num_writers is -released so that lockdep does not complain. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 32 +++++++++++++++++++++++++ - fs/btrfs/disk-io.c | 8 +++++++ - fs/btrfs/transaction.c | 53 ++++++++++++++++++++++++++++++++++-------- - 3 files changed, 83 insertions(+), 10 deletions(-) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index e886cf639c0f..f8172e269f03 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1098,6 +1098,7 @@ struct btrfs_fs_info { - */ - struct lockdep_map btrfs_trans_num_writers_map; - struct lockdep_map btrfs_trans_num_extwriters_map; -+ struct lockdep_map btrfs_state_change_map[4]; - - #ifdef CONFIG_BTRFS_FS_REF_VERIFY - spinlock_t ref_verify_lock; -@@ -1181,6 +1182,13 @@ enum { - BTRFS_ROOT_RESET_LOCKDEP_CLASS, - }; - -+enum btrfs_lockdep_trans_states { -+ BTRFS_LOCKDEP_TRANS_COMMIT_START, -+ BTRFS_LOCKDEP_TRANS_UNBLOCKED, -+ BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED, -+ BTRFS_LOCKDEP_TRANS_COMPLETED, -+}; -+ - /* - * Lockdep annotation for wait events. - * -@@ -1219,6 +1227,22 @@ enum { - #define btrfs_lockdep_release(owner, lock) \ - rwsem_release(&owner->lock##_map, _THIS_IP_) - -+/* -+ * Macros for the transaction states wait events, similar to the generic wait -+ * event macros. -+ */ -+#define btrfs_might_wait_for_state(owner, i) \ -+ do { \ -+ rwsem_acquire(&owner->btrfs_state_change_map[i], 0, 0, _THIS_IP_); \ -+ rwsem_release(&owner->btrfs_state_change_map[i], _THIS_IP_); \ -+ } while (0) -+ -+#define btrfs_trans_state_lockdep_acquire(owner, i) \ -+ rwsem_acquire_read(&owner->btrfs_state_change_map[i], 0, 0, _THIS_IP_) -+ -+#define btrfs_trans_state_lockdep_release(owner, i) \ -+ rwsem_release(&owner->btrfs_state_change_map[i], _THIS_IP_) -+ - /* Initialization of the lockdep map */ - #define btrfs_lockdep_init_map(owner, lock) \ - do { \ -@@ -1226,6 +1250,14 @@ enum { - lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \ - } while (0) - -+/* Initialization of the transaction states lockdep maps. */ -+#define btrfs_state_lockdep_init_map(owner, lock, state) \ -+ do { \ -+ static struct lock_class_key lock##_key; \ -+ lockdep_init_map(&owner->btrfs_state_change_map[state], #lock, \ -+ &lock##_key, 0); \ -+ } while (0) -+ - static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info) - { - clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags); -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 811d743e26e6..68c6cb4e9283 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -2992,6 +2992,14 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) - - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers); - btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters); -+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start, -+ BTRFS_LOCKDEP_TRANS_COMMIT_START); -+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked, -+ BTRFS_LOCKDEP_TRANS_UNBLOCKED); -+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_super_committed, -+ BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED); -+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_completed, -+ BTRFS_LOCKDEP_TRANS_COMPLETED); - - INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); - INIT_LIST_HEAD(&fs_info->space_info); -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index 44e47db4c8e8..d3576f84020d 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -550,6 +550,7 @@ static void wait_current_trans(struct btrfs_fs_info *fs_info) - refcount_inc(&cur_trans->use_count); - spin_unlock(&fs_info->trans_lock); - -+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED); - wait_event(fs_info->transaction_wait, - cur_trans->state >= TRANS_STATE_UNBLOCKED || - TRANS_ABORTED(cur_trans)); -@@ -868,6 +869,15 @@ static noinline void wait_for_commit(struct btrfs_transaction *commit, - u64 transid = commit->transid; - bool put = false; - -+ /* -+ * At the moment this function is called with min_state either being -+ * TRANS_STATE_COMPLETED or TRANS_STATE_SUPER_COMMITTED. -+ */ -+ if (min_state == TRANS_STATE_COMPLETED) -+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED); -+ else -+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED); -+ - while (1) { - wait_event(commit->commit_wait, commit->state >= min_state); - if (put) -@@ -1980,6 +1990,7 @@ void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans) - * Wait for the current transaction commit to start and block - * subsequent transaction joins - */ -+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); - wait_event(fs_info->transaction_blocked_wait, - cur_trans->state >= TRANS_STATE_COMMIT_START || - TRANS_ABORTED(cur_trans)); -@@ -2137,12 +2148,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - ktime_t interval; - - ASSERT(refcount_read(&trans->use_count) == 1); -+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); - - /* Stop the commit early if ->aborted is set */ - if (TRANS_ABORTED(cur_trans)) { - ret = cur_trans->aborted; -- btrfs_end_transaction(trans); -- return ret; -+ goto lockdep_trans_commit_start_release; - } - - btrfs_trans_release_metadata(trans); -@@ -2159,10 +2170,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - * Any running threads may add more while we are here. - */ - ret = btrfs_run_delayed_refs(trans, 0); -- if (ret) { -- btrfs_end_transaction(trans); -- return ret; -- } -+ if (ret) -+ goto lockdep_trans_commit_start_release; - } - - btrfs_create_pending_block_groups(trans); -@@ -2191,10 +2200,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - if (run_it) { - ret = btrfs_start_dirty_block_groups(trans); -- if (ret) { -- btrfs_end_transaction(trans); -- return ret; -- } -+ if (ret) -+ goto lockdep_trans_commit_start_release; - } - } - -@@ -2209,6 +2216,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - if (trans->in_fsync) - want_state = TRANS_STATE_SUPER_COMMITTED; -+ -+ btrfs_trans_state_lockdep_release(fs_info, -+ BTRFS_LOCKDEP_TRANS_COMMIT_START); - ret = btrfs_end_transaction(trans); - wait_for_commit(cur_trans, want_state); - -@@ -2222,6 +2232,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - cur_trans->state = TRANS_STATE_COMMIT_START; - wake_up(&fs_info->transaction_blocked_wait); -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); - - if (cur_trans->list.prev != &fs_info->trans_list) { - enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED; -@@ -2323,6 +2334,16 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - wait_event(cur_trans->writer_wait, - atomic_read(&cur_trans->num_writers) == 1); - -+ /* -+ * Make lockdep happy by acquiring the state locks after -+ * btrfs_trans_num_writers is released. If we acquired the state locks -+ * before releasing the btrfs_trans_num_writers lock then lockdep would -+ * complain because we did not follow the reverse order unlocking rule. -+ */ -+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED); -+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED); -+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED); -+ - /* - * We've started the commit, clear the flag in case we were triggered to - * do an async commit but somebody else started before the transaction -@@ -2332,6 +2353,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - if (TRANS_ABORTED(cur_trans)) { - ret = cur_trans->aborted; -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED); - goto scrub_continue; - } - /* -@@ -2466,6 +2488,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - mutex_unlock(&fs_info->reloc_mutex); - - wake_up(&fs_info->transaction_wait); -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED); - - ret = btrfs_write_and_wait_transaction(trans); - if (ret) { -@@ -2497,6 +2520,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - */ - cur_trans->state = TRANS_STATE_SUPER_COMMITTED; - wake_up(&cur_trans->commit_wait); -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED); - - btrfs_finish_extent_commit(trans); - -@@ -2510,6 +2534,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - */ - cur_trans->state = TRANS_STATE_COMPLETED; - wake_up(&cur_trans->commit_wait); -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED); - - spin_lock(&fs_info->trans_lock); - list_del_init(&cur_trans->list); -@@ -2538,7 +2563,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - - unlock_reloc: - mutex_unlock(&fs_info->reloc_mutex); -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED); - scrub_continue: -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED); -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED); - btrfs_scrub_continue(fs_info); - cleanup_transaction: - btrfs_trans_release_metadata(trans); -@@ -2556,6 +2584,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) - btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters); - btrfs_lockdep_release(fs_info, btrfs_trans_num_writers); - goto cleanup_transaction; -+ -+lockdep_trans_commit_start_release: -+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); -+ btrfs_end_transaction(trans); -+ return ret; - } - - /* --- -2.35.1 - diff --git a/queue-6.0/btrfs-add-macros-for-annotating-wait-events-with-loc.patch b/queue-6.0/btrfs-add-macros-for-annotating-wait-events-with-loc.patch deleted file mode 100644 index 7c57fc1a350..00000000000 --- a/queue-6.0/btrfs-add-macros-for-annotating-wait-events-with-loc.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 9b390e7dfd1a0faeff4012513dc4864e9df58bab Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:46 -0700 -Subject: btrfs: add macros for annotating wait events with lockdep - -From: Ioannis Angelakopoulos - -[ Upstream commit ab9a323f9ab576000795285dd7ac6afeedf29e32 ] - -Introduce four macros that are used to annotate wait events in btrfs code -with lockdep; - - 1) the btrfs_lockdep_init_map - 2) the btrfs_lockdep_acquire, - 3) the btrfs_lockdep_release - 4) the btrfs_might_wait_for_event macros. - -The btrfs_lockdep_init_map macro is used to initialize a lockdep map. - -The btrfs_lockdep_ macros are used by threads to take -the lockdep map as readers (shared lock) and release it, respectively. - -The btrfs_might_wait_for_event macro is used by threads to take the -lockdep map as writers (exclusive lock) and release it. - -In general, the lockdep annotation for wait events work as follows: - -The condition for a wait event can be modified and signaled at the same -time by multiple threads. These threads hold the lockdep map as readers -when they enter a context in which blocking would prevent signaling the -condition. Frequently, this occurs when a thread violates a condition -(lockdep map acquire), before restoring it and signaling it at a later -point (lockdep map release). - -The threads that block on the wait event take the lockdep map as writers -(exclusive lock). These threads have to block until all the threads that -hold the lockdep map as readers signal the condition for the wait event -and release the lockdep map. - -The lockdep annotation is used to warn about potential deadlock scenarios -that involve the threads that modify and signal the wait event condition -and threads that block on the wait event. A simple example is illustrated -below: - -Without lockdep: - -TA TB -cond = false - lock(A) - wait_event(w, cond) - unlock(A) -lock(A) -cond = true -signal(w) -unlock(A) - -With lockdep: - -TA TB -rwsem_acquire_read(lockdep_map) -cond = false - lock(A) - rwsem_acquire(lockdep_map) - rwsem_release(lockdep_map) - wait_event(w, cond) - unlock(A) -lock(A) -cond = true -signal(w) -unlock(A) -rwsem_release(lockdep_map) - -In the second case, with the lockdep annotation, lockdep would warn about -an ABBA deadlock, while the first case would just deadlock at some point. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Reviewed-by: David Sterba -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index df8c99c99df9..dfeb7174219e 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -1174,6 +1174,51 @@ enum { - BTRFS_ROOT_RESET_LOCKDEP_CLASS, - }; - -+/* -+ * Lockdep annotation for wait events. -+ * -+ * @owner: The struct where the lockdep map is defined -+ * @lock: The lockdep map corresponding to a wait event -+ * -+ * This macro is used to annotate a wait event. In this case a thread acquires -+ * the lockdep map as writer (exclusive lock) because it has to block until all -+ * the threads that hold the lock as readers signal the condition for the wait -+ * event and release their locks. -+ */ -+#define btrfs_might_wait_for_event(owner, lock) \ -+ do { \ -+ rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_); \ -+ rwsem_release(&owner->lock##_map, _THIS_IP_); \ -+ } while (0) -+ -+/* -+ * Protection for the resource/condition of a wait event. -+ * -+ * @owner: The struct where the lockdep map is defined -+ * @lock: The lockdep map corresponding to a wait event -+ * -+ * Many threads can modify the condition for the wait event at the same time -+ * and signal the threads that block on the wait event. The threads that modify -+ * the condition and do the signaling acquire the lock as readers (shared -+ * lock). -+ */ -+#define btrfs_lockdep_acquire(owner, lock) \ -+ rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_) -+ -+/* -+ * Used after signaling the condition for a wait event to release the lockdep -+ * map held by a reader thread. -+ */ -+#define btrfs_lockdep_release(owner, lock) \ -+ rwsem_release(&owner->lock##_map, _THIS_IP_) -+ -+/* Initialization of the lockdep map */ -+#define btrfs_lockdep_init_map(owner, lock) \ -+ do { \ -+ static struct lock_class_key lock##_key; \ -+ lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \ -+ } while (0) -+ - static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info) - { - clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags); --- -2.35.1 - diff --git a/queue-6.0/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch b/queue-6.0/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch index 6a082ed82d2..3014b80631d 100644 --- a/queue-6.0/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch +++ b/queue-6.0/btrfs-call-__btrfs_remove_free_space_cache_locked-on.patch @@ -62,14 +62,12 @@ Signed-off-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- - fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++-------------- + fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index 835071fa39a9..2f88053cfc5e 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c -@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, +@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btr struct btrfs_free_space *info, u64 offset, u64 bytes, bool update_stats); @@ -95,7 +93,7 @@ index 835071fa39a9..2f88053cfc5e 100644 static struct inode *__lookup_free_space_inode(struct btrfs_root *root, struct btrfs_path *path, u64 offset) -@@ -881,7 +900,14 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, +@@ -881,7 +900,14 @@ out: return ret; free_cache: io_ctl_drop_pages(&io_ctl); @@ -111,7 +109,7 @@ index 835071fa39a9..2f88053cfc5e 100644 goto out; } -@@ -1017,7 +1043,13 @@ int load_free_space_cache(struct btrfs_block_group *block_group) +@@ -1007,7 +1033,13 @@ int load_free_space_cache(struct btrfs_b if (ret == 0) ret = 1; } else { @@ -125,7 +123,7 @@ index 835071fa39a9..2f88053cfc5e 100644 btrfs_warn(fs_info, "block group %llu has wrong amount of free space", block_group->start); -@@ -2980,25 +3012,6 @@ static void __btrfs_return_cluster_to_free_space( +@@ -2970,25 +3002,6 @@ static void __btrfs_return_cluster_to_fr btrfs_put_block_group(block_group); } @@ -151,6 +149,3 @@ index 835071fa39a9..2f88053cfc5e 100644 void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl) { spin_lock(&ctl->tree_lock); --- -2.35.1 - diff --git a/queue-6.0/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch b/queue-6.0/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch deleted file mode 100644 index 5d6377a8f56..00000000000 --- a/queue-6.0/btrfs-change-the-lockdep-class-of-free-space-inode-s.patch +++ /dev/null @@ -1,61 +0,0 @@ -From a029bfa12be1da1c419fa9f774fbb645899d2832 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 Jul 2022 15:11:57 -0700 -Subject: btrfs: change the lockdep class of free space inode's invalidate_lock - -From: Ioannis Angelakopoulos - -[ Upstream commit 9d7464c87b159bbf763c24faeb7a2dcaac96e4a1 ] - -Reinitialize the class of the lockdep map for struct inode's -mapping->invalidate_lock in load_free_space_cache() function in -fs/btrfs/free-space-cache.c. This will prevent lockdep from producing -false positives related to execution paths that make use of free space -inodes and paths that make use of normal inodes. - -Specifically, with this change lockdep will create separate lock -dependencies that include the invalidate_lock, in the case that free -space inodes are used and in the case that normal inodes are used. - -The lockdep class for this lock was first initialized in -inode_init_always() in fs/inode.c. - -Reviewed-by: Josef Bacik -Signed-off-by: Ioannis Angelakopoulos -Signed-off-by: David Sterba -Signed-off-by: Sasha Levin ---- - fs/btrfs/free-space-cache.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index 85404c62a1c2..835071fa39a9 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -920,6 +920,8 @@ static int copy_free_space_cache(struct btrfs_block_group *block_group, - return ret; - } - -+static struct lock_class_key btrfs_free_space_inode_key; -+ - int load_free_space_cache(struct btrfs_block_group *block_group) - { - struct btrfs_fs_info *fs_info = block_group->fs_info; -@@ -989,6 +991,14 @@ int load_free_space_cache(struct btrfs_block_group *block_group) - } - spin_unlock(&block_group->lock); - -+ /* -+ * Reinitialize the class of struct inode's mapping->invalidate_lock for -+ * free space inodes to prevent false positives related to locks for normal -+ * inodes. -+ */ -+ lockdep_set_class(&(&inode->i_data)->invalidate_lock, -+ &btrfs_free_space_inode_key); -+ - ret = __load_free_space_cache(fs_info->tree_root, inode, &tmp_ctl, - path, block_group->start); - btrfs_free_path(path); --- -2.35.1 - diff --git a/queue-6.0/series b/queue-6.0/series index 1282207338d..e1cbe5c16fb 100644 --- a/queue-6.0/series +++ b/queue-6.0/series @@ -806,13 +806,6 @@ arm64-dts-imx8mm-kontron-use-the-vselect-signal-to-s.patch arm64-dts-imx8mq-librem5-add-bq25895-as-max17055-s-p.patch arm-orion-fix-include-path.patch btrfs-dump-extra-info-if-one-free-space-cache-has-mo.patch -btrfs-add-macros-for-annotating-wait-events-with-loc.patch -btrfs-add-lockdep-annotations-for-num_writers-wait-e.patch -btrfs-add-lockdep-annotations-for-num_extwriters-wai.patch -btrfs-add-lockdep-annotations-for-transaction-states.patch -btrfs-add-lockdep-annotations-for-pending_ordered-wa.patch -btrfs-change-the-lockdep-class-of-free-space-inode-s.patch -btrfs-add-lockdep-annotations-for-the-ordered-extent.patch btrfs-scrub-properly-report-super-block-errors-in-sy.patch btrfs-scrub-try-to-fix-super-block-errors.patch btrfs-don-t-print-information-about-space-cache-or-t.patch